Timofey and a tree

    xiaoxiao2021-03-26  19

    题意:

    给出一棵树,N-1条边 每个边的颜色C[i]。询问是否有一个节点作为根,他所有子树的颜色都相同。

    比赛结束好久了,才补题。心酸。

    思路:

    当时没写出来。也是想的是并查集分类,但是搞了90分钟没出。记录下各位博客学的两种比较好的方法

    方法一:

    对于两端颜色相同的边不予以判定,而对于颜色不同的边,必定是一个端点作为根进行整合。那么只需要记录下有多少个颜色不同的特殊边,并且对于每种特殊边,节点的度数加一,判断是否有某一节点的度数等于特殊边的条数即可

    #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <set> #include <vector> #define maxn 100005 using namespace std; const int inf=0x3f3f3f3f; int du[maxn]; int u[maxn],v[maxn],col[maxn]; int main() { int n; cin>>n; for(int i=1;i<n;i++) { cin>>u[i]>>v[i]; } for(int i=1;i<=n;i++) cin>>col[i]; int all=0; for(int i=1;i<n;i++) { if(col [ u[i] ]!= col[ v[i] ]) { all++; du[ u[i] ]++; du[ v[i] ]++; } } for(int i=1;i<=n;i++) { if(du[i]==all) { cout<<"YES"<<endl; cout<<i<<endl; return 0; } } cout<<"NO"<<endl; return 0; }

    方法二:

    将同色的分块,和方法一相同,但是用并查集来将树分块。

    #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <set> #include <vector> #define maxn 100005 using namespace std; const int inf=0x3f3f3f3f; int du[maxn]; int u[maxn],v[maxn],col[maxn],vis[maxn]; int father[maxn]; vector <int > relation[maxn]; int find(int x) { if(father[x]!=x) father[x]=find(father[x]); return father[x]; } int Union(int x,int y) { int rootx=find(x); int rooty=find(y); if(rootx!=rooty) { father[rootx]=rooty; } return 0; } int main() { int n; cin>>n; for(int i=1;i<=n;i++) father[i]=i; for(int i=1;i<n;i++) { cin>>u[i]>>v[i]; } for(int i=1;i<=n;i++) cin>>col[i]; int all=0; for(int i=1;i<n;i++) { if(col[u[i]]==col[v[i]]) Union(u[i],v[i]); else all++; } for(int i=1;i<n;i++) { int rootx=find(u[i]); int rooty=find(v[i]); if(rootx!=rooty) { du[u[i]]++; du[v[i]]++; } } for(int i=1;i<=n;i++) { if(du[i]==all) { cout<<"YES"<<endl; cout<<i<<endl; return 0; } } cout<<"NO"<<endl; return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-659599.html

    最新回复(0)