你知道一些算法(优于强力),它可以在图中找到由一个顶点分隔并且彼此之间没有连接的顶点。例如:
在此图表中找到的路径为:
最好的是c ++代码,它使用stl列表数组作为图形表示,但任何其他过程语言或伪代码中的代码也可以。
答案 0 :(得分:1)
一种方法是基于广度优先搜索,对于图中的每个顶点i
,我们扫描与i
相邻的顶点附近的顶点(即两个邻接级别) !)。
mark = array[0..n-1] of 0
flag = 1
for i = nodes in graph do
// mark pattern of nodes adjacent to i
mark[i] = flag
for j = nodes adjacent to i do
mark[j] = flag
endfor
// scan nodes adjacent to those adjacent to i
// (separated by one vertex!)
for j = nodes adjacent to i do
for k = nodes adjacent to j do
if mark[k] != flag and k > i then
// i,k are separated by another vertex
// and there is no edge i,k
// prevent duplicates
mark[k] = flag
endif
endfor
endfor
// implicit unmarking of current pattern
flag += 1
endfor
如果图表每个顶点有m
个边,则这将是O(n * m^2)
算法,需要O(n)
个额外空间。
答案 1 :(得分:1)
这个问题的一个简单直观的解决方案在于邻接矩阵。我们知道,(i,j)邻接矩阵的第n个幂的元素列出了i和j之间的所有长度n的路径。
所以我只读A,邻接矩阵,然后计算A ^ 2。最后,我列出了它们之间只有一条长度为2的路径的所有对。
//sg
#include<stdio.h>
#define MAX_NODE 10
int main()
{
int a[MAX_NODE][MAX_NODE],c[MAX_NODE][MAX_NODE];
int i,j,k,n;
printf("Enter the number of nodes : ");
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<=i;j++)
{
printf("Edge from %d to %d (1 yes/0 no) ? : ",i+1,j+1);
scanf("%d",&a[i][j]);
a[j][i]=a[i][j]; //undirected graph
}
//dump the graph
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
c[i][j]=0;
printf("%d",a[i][j]);
}
printf("\n");
}
printf("\n");
//multiply
for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(k=0;k<n;k++)
{
c[i][j]+=a[i][k]*a[k][j];
}
//result of the multiplication
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d",c[i][j]);
}
printf("\n");
}
for(i=0;i<n;i++)
for(j=0;j<=i;j++)
{
if(c[i][j]==1&&(!a[i][j])&&(i!=j)) //list the paths
{
printf("\n%d - %d",i+1, j+1 );
}
}
return 0;
}
为您的图表运行示例
[aman@aman c]$ ./Adjacency2
Enter the number of nodes : 5
Edge from 1 to 1 (1 yes/0 no) ? : 0
Edge from 2 to 1 (1 yes/0 no) ? : 1
Edge from 2 to 2 (1 yes/0 no) ? : 0
Edge from 3 to 1 (1 yes/0 no) ? : 1
Edge from 3 to 2 (1 yes/0 no) ? : 1
Edge from 3 to 3 (1 yes/0 no) ? : 0
Edge from 4 to 1 (1 yes/0 no) ? : 0
Edge from 4 to 2 (1 yes/0 no) ? : 0
Edge from 4 to 3 (1 yes/0 no) ? : 1
Edge from 4 to 4 (1 yes/0 no) ? : 0
Edge from 5 to 1 (1 yes/0 no) ? : 0
Edge from 5 to 2 (1 yes/0 no) ? : 0
Edge from 5 to 3 (1 yes/0 no) ? : 0
Edge from 5 to 4 (1 yes/0 no) ? : 1
Edge from 5 to 5 (1 yes/0 no) ? : 0
01100
10100
11010
00101
00010
21110
12110
11301
11020
00101
4 - 1
4 - 2
5 - 3
<强>分析强>
对于n个顶点:
时间:O(n ^ 3)。可以减少到O(n^2.32),这是非常好的。
空格:O(n ^ 2)。
答案 2 :(得分:0)
您可以使用Warshall's algorithm的改编版本执行此操作。以下代码示例中的算法使用图形的邻接矩阵,如果存在则打印i j
是从i
到k
的边缘,从k
到j
的边缘,但没有从i
到j
的直接路径。
#include <iostream>
int main() {
// Adjacency Matrix of your graph
const int n = 5;
bool d[n][n] = {
{ 0, 1, 1, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
};
// Modified Warshall Algorithm
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
if (d[i][k])
for (int j = 0; j < n; j++)
if (d[k][j] && !d[i][j])
std::cout << i + 1 << " " j + 1 << std::endl;
}
您可以查看结果online。