hdu 3367 伪森林,not 最大生成树
感觉题意很扭曲。。。
不是求最大生成树!给一个图,求pseudoforest伪森林,要求每个连通分量最多可以有一个环。求能构成的最大值。
错误写法,求出最大生成树+最大的边
正确写法:在求最大生成树的思路的基础上每次判断一下环的问题~
6 7
0 1 9
0 2 6
1 2 8
3 4 5
4 5 5
3 5 4
2 4 1
这组数据如果是错误的方法就是34,选择(0,1),(1,2),(0,2),(2,4),(3,4),(4,5)
正确的方法答案是37,选择(0,1),(1,2),(0,2),(3,4),(3,5),(4,5)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const int N=10010; 7 int n,m; 8 int father[N]; 9 int circle[N]; 10 struct edge{ 11 int x,y,z; 12 }e[10*N]; 13 int find(int x){ 14 if(x!=father[x]){ 15 father[x]=find(father[x]); 16 } 17 return father[x]; 18 } 19 int cmp(edge e1,edge e2){ 20 return e1.z>e2.z; 21 } 22 int Kruskal(){ 23 int i,j,ans=0; 24 memset(circle,0,sizeof(circle)); 25 for(i=0;i<m;i++){ 26 int x=find(e[i].x); 27 int y=find(e[i].y); 28 if(x==y){ 29 if(!circle[x]){ 30 circle[x]=1; 31 ans+=e[i].z; 32 } 33 continue ; 34 } 35 if(circle[x]&&circle[y]) continue; 36 if(circle[x]&&!circle[y]){ 37 father[y]=x; 38 }else{ 39 father[x]=y; 40 } 41 ans+=e[i].z; 42 //printf("(%d,%d) %d res=%d\n",e[i].x,e[i].y,e[i].z,ans); 43 } 44 return ans; 45 } 46 int main(){ 47 int i,j; 48 while(scanf("%d%d",&n,&m)!=EOF){ 49 if(n==0&&m==0) break; 50 for(i=0;i<n;i++){ 51 father[i]=i; 52 } 53 for(i=0;i<m;i++){ 54 scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z); 55 } 56 sort(e,e+m,cmp); 57 printf("%d\n",Kruskal()); 58 } 59 return 0; 60 }