CodeForces - 763A(并查集/思维)
Posted mcq1999
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 763A(并查集/思维)相关的知识,希望对你有一定的参考价值。
题意
https://vjudge.net/problem/CodeForces-763A
一棵无根树中各个节点被染上了一种颜色c[i]
现在让你选择一个点作为根节点,使得这个根节点的所有儿子满足以该儿子节点的作为根的子树中所有点颜色均相同(不同儿子为根的子树颜色可以不同)
思路
俺的方法:
暴力水过。用并查集把相同颜色的连了边的点缩点,然后枚举每个点作为答案,判断这个点所连的的所有点的所在相同颜色连通块的大小之和是否等于n-1即可(除去自己这个点)。
正解:
先计算每个点与所连的点的颜色不同的点数,把两端颜色不同的边数也记录。如果某个点与连的点的不同颜色的个数==所有颜色不同的边数,那么这个点就是满足条件的。
这样想,作为根的这个点连的其他连通块肯定每个连通块颜色都是相同的,那么颜色不同的边只能在根这个点产生。
代码
俺的:
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=100005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int c[N],pre[N]; vector<int> g[N]; int flag=0; int find(int x) { if(x==pre[x]) return x; return pre[x]=find(pre[x]); } set<int> s[N]; int main() { std::ios::sync_with_stdio(false); int n; cin>>n; for(int i=1; i<n; i++) { int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } int q,mx=0; for(int i=1; i<=n; i++) { cin>>c[i]; pre[i]=i; } for(int i=1; i<=n; i++) { int sz=g[i].size(); for(int j=0; j<sz; j++) { if(c[i]==c[g[i][j]]) { int fi=find(i),fj=find(g[i][j]); if(fi!=fj) pre[fj]=fi; } } } for(int i=1; i<=n; i++) { s[find(i)].insert(i); } int p,f=0; for(int i=1; i<=n; i++) { int sum=0; int sz=g[i].size(); for(int j=0; j<sz; j++) { int v=g[i][j]; sum+=s[find(v)].size(); } // cout<<i<<" "<<sum<<endl; if(s[i].size()!=1) { sum--; } if(sum==n-1) { p=i; flag=1; break; } } if(!flag) cout<<"NO"<<endl; else { cout<<"YES"<<endl; cout<<p<<endl; } return 0; } /* 7 1 7 1 3 1 4 4 5 1 2 2 6 3 2 1 2 2 2 2 */ /* 8 1 4 2 4 3 4 4 8 1 7 2 5 2 6 2 1 8 2 1 1 2 6 */
正解:
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=100005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int c[N],s[N],u[N],v[N]; int main() { std::ios::sync_with_stdio(false); int n; cin>>n; for(int i=1; i<n; i++) { cin>>u[i]>>v[i]; } int q,mx=0; for(int i=1; i<=n; i++) { cin>>c[i]; } int sum=0; for(int i=1;i<n;i++) { if(c[u[i]]!=c[v[i]]) s[u[i]]++,s[v[i]]++,sum++; } for(int i=1;i<=n;i++) { if(s[i]==sum) { cout<<"YES"<<endl<<i<<endl; return 0; } } cout<<"NO"<<endl; return 0; }
以上是关于CodeForces - 763A(并查集/思维)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 200A Cinema 并查集 + 思维 (看题解)
Codeforces Round #423 (Div. 2) C 思维,并查集 或 线段树 D 树构造,水