Friendly Group ###K ###K //K

题目链接:https://vjudge.net/contest/402831#problem/E

题意:给定n个人 m个关系,每有一个关系中的两人都去的话就 贡献+1 只去了一个就减1  再减去总共去的人数

思路: 考虑每一个连通块 边-去点就是贡献, 每次找贡献大于0的加入ans即可

可以有并查集或者dfs两种做法, dfs的话注意处理加边的时候别重复,并查集注意连通块合并的时候转移ans

 

dfs

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =3e5+10;
 6 //const int mod=998244353;
 7 vector<int>E[maxn];
 8 int vis[maxn];
 9 int num[maxn];
10 int temp1=0;
11 int temp2=0;
12 
13 void dfs(int u)
14 {
15     vis[u]=1;
16     temp1++;
17     temp2+=E[u].size()-num[u];
18     for(auto &v:E[u])
19     {
20         if(!vis[v])
21         num[v]++;
22     }
23     for(auto &v:E[u])
24     {
25         if(vis[v])
26             continue;
27         dfs(v);
28     }
29 }
30 
31 int main()
32 {
33     ios::sync_with_stdio(false);
34     cin.tie(0);
35     int t;
36     cin>>t;
37     int cnt=0;
38     while(t--)
39     {
40         int n,m;
41         cin>>n>>m;
42         for(int i=1;i<=n;i++)
43         {
44             E[i].clear();
45             vis[i]=num[i]=0;
46         }
47         while(m--)
48         {
49             int x,y;
50             cin>>x>>y;
51             E[x].pb(y);
52             E[y].pb(x);
53         }
54         int ans=0;
55         for(int i=1;i<=n;i++)
56         {
57             if(vis[i])
58                 continue;
59 
60             temp1=0;
61             temp2=0;
62             dfs(i);
63             ans+=max(0,temp2-temp1);
64         }
65         cout<<"Case #"<<++cnt<<": "<<ans<<'\n';
66 
67 
68 
69     }
70 
71 
72 }
View Code

 

并查集

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =3e5+10;
 6 const int mod=998244353;
 7 int f[maxn];
 8 int ans[maxn];
 9 
10 int find1(int x)
11 {
12     if(f[x]==x)
13         return x;
14     return f[x]=find1(f[x]);
15 }
16 int num[maxn];
17 
18 
19 
20 int main()
21 {
22     ios::sync_with_stdio(false);
23     cin.tie(0);
24     int t;
25     cin>>t;
26     int cnt=0;
27     while(t--)
28     {
29         int n,m;
30         cin>>n>>m;
31         for(int i=1;i<=n;i++)
32             f[i]=i,num[i]=0,ans[i]=0;
33         while(m--)
34         {
35             int x,y;
36             cin>>x>>y;
37             int t1=find1(x),t2=find1(y);
38             if(t1==t2)
39             {
40                 ans[t1]++;
41             }
42             else
43             {
44                 f[t2]=t1;
45                 ans[t1]+=ans[t2];
46                 ans[t1]++;
47             }
48         }
49         for(int i=1;i<=n;i++)
50         {
51             num[find1(i)]++;
52         }
53          int sum=0;
54         for(int i=1;i<=n;i++)
55         {
56             if(num[i]>=2)
57             sum+=max(0,ans[i]-num[i]);
58         }
59         cout<<"Case #"<<++cnt<<": "<<sum<<'\n';
60 
61 
62 
63     }
64 
65 
66 }
View Code

 

posted @ 2020-10-21 09:40  canwinfor  阅读(417)  评论(0)    收藏  举报