codeforces 400 D Dima and Bacteria【并查集 Floyd】

题意:给出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
");
61                 return 0;
62             }
63         }
64     }
65     printf("Yes
");
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("
");
78       }
79       
80       return 0;
81 }
View Code
原文地址:https://www.cnblogs.com/wuyuewoniu/p/4480559.html