题意:给出n个点,分别属于k个集合,判断每个集合里面的点的距离都为0,为0的话输出yes,并输出任意两个集合之间的最短路
这道题目有两个地方不会处理,
先是n个点,分别属于k个集合,该怎么记录下来这里,
然后就是判断每个集合里面的点的距离是否为1,这里可以用并查集来做,如果在输入点的时候,距离为0,就将这两点合并
最后判断每个点,如果他们同属于一个集合,判断它俩的根是否一样就可以了
最后用floyd求最短路
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) 14 15 typedef long long LL; 16 const int INF = (1<<30)-1; 17 const int mod=1000000007; 18 const int maxn=1005; 19 20 int in[maxn*maxn],d[maxn][maxn],p[maxn*maxn]; 21 22 int find(int x){ return x==p[x]? x:p[x]=find(p[x]);} 23 24 int main(){ 25 int n,m,k; 26 scanf("%d %d %d",&n,&m,&k); 27 int sum=0; 28 for(int i=1;i<=k;i++){ 29 int c; 30 cin>>c; 31 for(int j=sum+1;j<=sum+c;j++) in[j]=i; 32 sum+=c; 33 } 34 35 for(int i=1;i<=k;i++){//?????floyed???? 36 for(int j=1;j<=k;j++){ 37 if(i==j) d[i][j]=0; 38 else d[i][j]=INF; 39 } 40 } 41 for(int i=1;i<=n;i++) p[i]=i; 42 43 while(m--){ 44 int u,v,w; 45 cin>>u>>v>>w; 46 if(in[u]!=in[v]&&d[in[u]][in[v]]>w) d[in[u]][in[v]]=d[in[v]][in[u]]=w; 47 48 if(w==0){ 49 int x=find(u); 50 int y=find(v); 51 if(x!=y) p[x]=y; 52 } 53 } 54 55 for(int i=2;i<=n;i++){ 56 if(in[i]==in[i-1]){ 57 int x=find(i); 58 int y=find(i-1); 59 if(x!=y){ //?????????????????????????????????????ò???0?????NO 60 printf("No\n"); 61 return 0; 62 } 63 } 64 } 65 printf("Yes\n"); 66 67 for(int p=1;p<=k;p++) 68 for(int i=1;i<=k;i++) 69 for(int j=1;j<=k;j++) 70 d[i][j]=min(d[i][j],d[i][p]+d[p][j]); 71 72 for(int i=1;i<=k;i++){ 73 for(int j=1;j<=k;j++){ 74 if(d[i][j]==INF) printf("-1 "); 75 else printf("%d ",d[i][j]); 76 } 77 printf("\n"); 78 } 79 80 return 0; 81 }
时间: 2024-10-27 11:01:56