JZOJ.5275【NOIP2017模拟8.14】水管

Description

 

Input

Output

 

Sample Input

1 
5 7 
1 2 2 
1 4 1 
2 4 2 
4 3 2 
2 3 1 
4 5 1 
1 5 2

Sample Output

5
No
 

Data Constraint

 

Hint


 这个第一问很显然就是最小生成树了,跑一下kruskal或者prim就可以了。

至于第二问问是不是唯一的最小生成树,我们在跑kruskal的时候,我们可以把已经联通的点缩成一个点,然后发现一条连接某两个点的边,便再寻找是否还有其他边权值一样的边也连接着这两个点,如果有就说明最小生成树并不是唯一的。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #define N 100002
 8 using namespace std;
 9 struct data{
10     int a,b,c;
11 }line[N*2];
12 int n,t,f[N],tmp,x,y,m;
13 long long ans;
14 bool qwq;
15 int find(int x){
16     if (f[x]==x) return x;
17     f[x]=find(f[x]);
18     return f[x];
19 }
20 bool comp(const struct data a,const struct data b){
21     return a.c<b.c;
22 }
23 int main(){
24     scanf("%d",&t);
25     while (t--){
26         qwq=false;
27         scanf("%d%d",&n,&m);
28         for (int i=1;i<=m;i++){
29             scanf("%d%d%d",&line[i].a,&line[i].b,&line[i].c);
30             if (i<=n) f[i]=i;
31         }
32     sort(line+1,line+1+m,comp);
33     tmp=0;
34     ans=0;
35     for (int i=1;i<=m;i++){
36         if (tmp==n-1) break;
37         x=find(line[i].a);
38         y=find(line[i].b);
39         if (x!=y){
40             if (!qwq)
41             for (int j=i+1,qoq,qvq;j<=m&&line[j].c==line[i].c;j++){
42              qoq=find(line[j].a);
43              qvq=find(line[j].b);
44              if (((qoq==x)&&(qvq==y))||((qoq==y)&&(qvq==x))){
45                  qwq=true;
46                  break;
47              }
48             }
49         f[x]=y;
50         tmp++;
51         ans+=line[i].c;
52         }
53     }
54     printf("%lld\n",ans);
55     if (qwq) printf("No\n");
56     else printf("Yes\n");
57     }
58     return 0;
59 }
神奇的代码

 

(其实这个很容易就被卡的似乎只是数据太水了233)

 

posted @ 2017-08-14 21:35  ~Lanly~  阅读(194)  评论(0编辑  收藏  举报