题目描述
给定有向图的邻接矩阵A,其元素定义为:若存在顶点i到顶点j的有向边则A[i,j]=1,若没有有向边则A[i,j]=0。试求A的可达闭包矩阵A*,其元素定义为:若存在顶点i到顶点j的有向路径则A*[i,j]=1,若没有有向路径则A*[i,j]=0。
输入
第1行顶点个数n
第2行开始的n行有向图的邻接矩阵,元素之间由空格分开
输出
有向图的可达闭包矩阵A*,元素之间由空格分开
输入样例1
4
0 1 0 1
0 0 1 0
0 0 0 0
0 0 0 0
输出样例1
0 1 1 1
0 0 1 0
0 0 0 0
0 0 0 0
NOTICE:两个顶点之间存在有向路径,则从这个其中一个顶点出发遍历可以到达另一个顶点,BFS或DFS都可以;算法很简单,但需要注意的是,如果一个顶点通过有向路径可以回到自身,则对应可达闭包矩阵也是1,因此,我们在遍历的时候先不要把起点的flag改为1,让它保持为0,看最后能不能回来;
#include <iostream>
#include <queue>
using namespace std;
class Graph
{
private:
int** Matrix;
int** matrix;//可达闭包矩阵
int vertexnum;
int* flag;
public:
Graph()
{
cin >> vertexnum;
Matrix = new int* [vertexnum];
for (int i = 0; i < vertexnum; i++)
Matrix[i] = new int[vertexnum];
matrix = new int* [vertexnum];
for (int i = 0; i < vertexnum; i++)
matrix[i] = new int[vertexnum];
flag = new int[vertexnum];
for (int i = 0; i < vertexnum; i++)
flag[i] = 0;
for (int i = 0; i < vertexnum; i++)
for (int j = 0; j < vertexnum; j++)
cin >> Matrix[i][j];
}
~Graph()
{
for (int i = 0; i < vertexnum; i++)
delete[]Matrix[i];
delete[]Matrix;
}
int BFS(int index, int end)
{
queue<int> q;
q.push(index);
//flag[index] = 1; 起点保持未访问,因为如果路径可以回到起点的话也算
while (!q.empty())
{
for (int i = 0; i < vertexnum; i++)
if (Matrix[q.front()][i] && !flag[i])
{
q.push(i);
flag[i] = 1;
}
q.pop();
if (!q.empty() && q.front() == end)//放在后面防止当i==j时直接返回1,注意这里要加个q非空的条件
return 1;
}
return 0;
}
void test()
{
for (int i = 0; i < vertexnum; i++)
{
for (int j = 0; j < vertexnum; j++)
{
//重置
for (int i = 0; i < vertexnum; i++)
flag[i] = 0;
if (BFS(i, j))
matrix[i][j] = 1;
else
matrix[i][j] = 0;
}
}
}
void display()
{
for (int i = 0; i < vertexnum; i++)
for (int j = 0; j < vertexnum; j++)
{
cout << matrix[i][j];
if (j == vertexnum - 1)
cout << endl;
else
cout << " ";
}
}
};
int main()
{
Graph g;
g.test();
g.display();
return 0;
}