hdu3367最大伪森林(并查集)

题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3367/

题目要求一个连通图的最大伪森林,伪森林是一个最多有一个回路的图。我们只要用Kruskal最大生成树的策略就可以,给根节点表上记号表明这棵树有没有负环。其实也有一些贪心的思想。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define mp(a,b) make_pair((a),(b))
17 #define P pair<int,int>
18 #define dbg(args) cout<<#args<<":"<<args<<endl;
19 #define inf 0x3f3f3f3f
20 const int maxn=1e6+10;
21 int n,m,t;
22 inline int read(){
23     int ans=0,w=1;
24     char ch=getchar();
25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
27     return ans*w;
28 }
29 int f[maxn];
30 bool mark[maxn];
31 struct node{
32     int u,v,w;
33 }e[maxn];
34 int ans;
35 void init()
36 {
37     f(i,0,n-1)f[i]=i;
38     mem(mark,0);
39     ans=0;
40 }
41 bool cmp(node& a,node& b)
42 {
43     return a.w>b.w;
44 }
45 int find(int x)
46 {
47     if(x==f[x])return x;
48     return f[x]=find(f[x]);
49 }
50 void Union(int x,int y,int w)
51 {
52     int fx=find(x);
53     int fy=find(y);
54     if(fx==fy)
55     {
56         if(!mark[fx])
57         {
58             mark[fx]=1;
59             ans+=w;
60         }
61     }
62     else 
63     {
64         if(!mark[fx]||!mark[fy])
65         {
66             f[fx]=fy;
67             mark[fy]=mark[fx]||mark[fy];//两者都为零的时候fy不做标记,但是两者中有一个是零的时候就会做标记 
68             ans+=w;
69         }
70     }
71 }
72 int main()
73 {
74     //freopen("input.txt","r",stdin);
75     //freopen("output.txt","w",stdout);
76     std::ios::sync_with_stdio(false);
77     while(1)
78     {
79         n=read(),m=read();
80         init();
81         if(n==0&&m==0)break;
82         f(i,1,m)
83         {
84             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
85         }
86         sort(e+1,e+m+1,cmp);
87         f(i,1,m)
88         {
89             Union(e[i].u,e[i].v,e[i].w);
90         }
91         pf("%d\n",ans); 
92     }
93  } 

 

posted @ 2020-03-24 21:19  WA自动机~  阅读(148)  评论(0编辑  收藏  举报