判断一个集合内的点能否以花费为0互相抵达。。。。求集合间的最短路
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,k,pos=1;
int be[110000];
int g[600][600];
int fa[110000];
void init()
{
for(int i=1;i<=n;i++) fa[i]=i;
}
int Find(int x)
{
if(x==fa[x]) return x;
return fa[x]=Find(fa[x]);
}
void Union(int a,int b)
{
int A=Find(a),B=Find(b);
if(A==B) return ;
fa[A]=B;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
memset(g,63,sizeof(g));
init();
for(int i=1; i<=k; i++)
{
g[i][i]=0;
int c;
scanf("%d",&c);
for(int j=pos; j<pos+c; j++) be[j]=i;
pos=pos+c;
}
for(int i=0; i<m; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(c==0) Union(a,b);
a=be[a],b=be[b];
g[a][b]=g[b][a]=min(g[b][a],c);
}
int mark=-1,SINE; bool flag=true;
for(int i=1;i<=n;i++)
{
if(be[i]!=mark) SINE=Find(i),mark=be[i];
else if(Find(i)!=SINE) {flag=false; break;};
}
if(!flag) {puts("No");return 0;} else puts("Yes");
for(int l=1; l<=k; l++)
{
for(int i=1; i<=k; i++)
{
for(int j=1; j<=k; j++)
{
g[i][j]=min(g[i][j],g[i][l]+g[l][j]);
}
}
}
for(int i=1; i<=k; i++)
{
for(int j=1; j<=k; j++)
{
int t=(g[i][j]==INF)?-1:g[i][j];
printf("%d ",t);
}
putchar(10);
}
return 0;
}