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 }
并查集
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 }

浙公网安备 33010602011771号