hdu 3367 伪森林(kruskal)

http://acm.hdu.edu.cn/showproblem.php?pid=3367

求pseudoforest伪森林,要求每个连通分量最多可以有一个环。求能构成的最大值

我是用kruskal的方法按照求最大生成树那样求的,只不过要加一个判断,就是判断两颗子树是够成环,如果各成环,就不能合并,如果只有其中一个成环或者都不成环,那么就可以合并,并对其进行标记。。。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 const int N=10010;
 6 using namespace std;
 7 
 8 int n,m;
 9 int parent[N];
10 int visited[N];//用来标记是否存在环
11 
12 struct Edge {
13     int u,v,w;
14     bool operator < (const Edge &p) const {
15         return p.w<w;//从大到小
16     }
17 }edge[N*10];
18 
19 
20 //初始化
21 void UFset(){
22     for(int i=0;i<n;i++)
23         parent[i]=-1;
24 }
25 
26 int Find(int x){
27     int s;
28     for(s=x;parent[s]>=0;s=parent[s]);
29     //路径压缩,优化
30     while(s!=x){
31         int temp=parent[x];
32         parent[x]=s;
33         x=temp;
34     }
35     return s;
36 }
37 
38 //合并
39 void Union(int R1,int R2){
40     int r1=Find(R1);
41     int r2=Find(R2);
42     int temp=parent[r1]+parent[r2];
43     if(parent[r1]>parent[r2]){
44         parent[r1]=r2;
45         parent[r2]=temp;
46     }else {
47         parent[r2]=r1;
48         parent[r1]=temp;
49     }
50 }
51 
52 
53 int main(){
54     while(scanf("%d%d",&n,&m)!=EOF){
55         if(n==0&&m==0)break;
56         memset(visited,0,sizeof(visited));
57         int u,v,ans=0;
58         for(int i=0;i<m;i++){
59             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
60         }
61         sort(edge,edge+m);
62         UFset();
63         for(int i=0;i<m;i++){
64             u=Find(edge[i].u);
65             v=Find(edge[i].v);
66             if(u!=v){
67                 if(visited[u]&&visited[v])continue;  //都存在环
68                 if(visited[u]||visited[v])
69                     visited[u]=visited[v]=1;
70                 ans+=edge[i].w;
71                 Union(u,v);
72             }else if(!visited[u]||!visited[v]){
73                 Union(u,v);
74                 visited[u]=visited[v]=1;
75                 ans+=edge[i].w;
76             }
77         }
78         printf("%d\n",ans);
79     }
80     return 0;
81 }
82 
83                 
原文地址:https://www.cnblogs.com/wally/p/2891138.html