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\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 }
View Code

 

你可能感兴趣的:(codeforces)