拆地毯——kruskal最大生成树
P2121 拆地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这道题很简单,就是最大生成树。但是之前接触的都是最小生成树,其实就是把排序变成从大到小排序。因为只留下k条地毯,所以当k条地毯在同一个连通块后,我们就可以输出求和的答案,然后结束。
唯一的亮点就是排序是从大到小。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N=2e5+100; 5 int n,m,k,idx,h[N],p[N]; 6 int ans; 7 8 struct node 9 { 10 int a,b,w; 11 }e[N]; 12 13 14 bool cmp(const node&s1,const node&s2) 15 { 16 return s1.w>s2.w; 17 } 18 19 int find(int x) 20 { 21 if(p[x]!=x)p[x]=find(p[x]); 22 return p[x]; 23 } 24 25 void kruskal() 26 { 27 sort(e+1,e+1+m,cmp); 28 for(int i=1;i<=n;i++)p[i]=i; 29 30 int q=0; 31 for(int i=1;i<=m;i++) 32 { 33 int a=e[i].a,b=e[i].b,w=e[i].w; 34 if(find(a)!=find(b)) 35 { 36 ans+=w; 37 q++; 38 p[find(a)]=find(b); 39 } 40 if(q==k) 41 { 42 printf("%d\n",ans); 43 return ; 44 } 45 } 46 } 47 48 49 int main() 50 { 51 scanf("%d%d%d",&n,&m,&k); 52 for(int i=1;i<=m;i++) 53 { 54 int u,v,w; 55 scanf("%d%d%d",&u,&v,&w); 56 e[i].a=u,e[i].b=v,e[i].w=w; 57 } 58 59 kruskal(); 60 61 return 0; 62 }