Warshall算法求有向图的传递闭包

1定义是这样给出的,传递闭包:对于任何关系 R,R 的传递闭包总是存在的。传递关系的任何家族的交集也是传递的。进一步的,至少存在一个包含 R 的传递关系,也就是平凡的: X × X。R 传递闭包给出自包含 R 的所有传递关系的交集……其实就是求点与点之间的可达关系,比如1–>4,4–>6,那么1–>6,用warshall算法可以求出有向图的传递闭包,推荐一篇相关的博客传送门

#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

#define pi acos(-1.0)
#define e exp(1.0)
typedef long long ll;
const ll maxn=1e2+7;//有向图的传递闭包 
ll N,M;//N是顶点数,M是边的数量
ll War[maxn][maxn]; 
int main()
{
// freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin>>N>>M;
	ll i,j,k;
	memset(War,0,sizeof(War));//初始化图
	for(i=1;i<=N;i++)
	War[i][i]=1;//自身可达 
	for(i=1;i<=M;i++)
	{
		ll u,v;
		cin>>u>>v;
		War[u][v]=1;//表明顶点u到顶点v直降有一条边相连 
	}
	for(k=1;k<=N;k++)//以点k为中间点,作为桥梁 ,遍历每一个中间点,来更新传递关系 
	{
		for(i=1;i<=N;i++)
		{
			for(j=1;j<=N;j++)
			{
				if(War[i][j]||(War[i][k]&&War[k][j]))//如果i-->j本身可达或者i-->k,k-->j,那么i-->j 
				War[i][j]=1;
			}
		}
	}
	for(i=1;i<=N;i++)//打印输出 
	{
		for(j=1;j<=N;j++)
		cout<<i<<"-->"<<j<<' '<<War[i][j]<<endl;
	}
	return 0; 
}

2需要注意的是这个算法的复杂度是(N^3)的,N是点数

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务