问题: 一个 n 个节点的有向图的传递闭包可以定义为一个 n 阶布尔矩阵 T,使得当
第 i 个顶点到第 j 个顶点的路径长度为正时,T[i, j]=1;否则,T[i, j]=0
( i>=1,j<=n)。请设计一个算法来求该传递闭包,并分析你设计的算法的时
间复杂度。
思路:
定义一个二维数组,例如a[i][j],i,j属于[1,N]表示这个矩阵;用dp[i][j]表示i与j之间的连接关系;当i,j直接相连或间接相连dp[i][j]=1,否则dp[i][j]=0; 点i与j的联通关系判断,借助floyd算法;这道题的思路非常巧妙,就是利用Floyd的最短路径,假设能找到“最短路径”则证明是连通的,不能则证明不联通;
Floyd算法大概思想:依次扫描每一点(k),并以该点作为中介点,计算出通过k点的其他任意两点(i,j)的最短距离,这就是floyd算法的精髓
也就是说起点i 直接到达终点 j 最短 还是从i 出发 经过中间 若干点 k 到达 j 最短;
实现只需要三个循环:
for(int k=1;k<=N;k++)
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])}
这题不要统计最短路径,只需要判断联通不连通即可,借助类似的思想,i与j的联通关系可以用map[i][j]进行表达1表示联通,0表示不联通
具体实现:
#include<iostream>
using namespace std;
int N;//矩阵的维度
int Q;
int x,y;
int G[305][305];//矩阵大小初始化
int map[305][305];//各结点联通关系判断矩阵1表示联通,0非联通;可以用二维布尔矩阵进行表示
int main(){
cin>>N;//实际矩阵的大小
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
cin>>G[i][j];//矩阵元素赋值
}
}
//点连通关系建立
for(int k=1;k<=N;k++)
{
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++){
if(G[i][j]==1||(G[i][k]==1&&G[k][j]==1)){
map[i][j]=1;//连通
}
}
}
}
return 0;
}