前言,根据最终图的样貌搞真厉害
“缩点判根度为结点数-1”牛逼
-----
题意:
找一个根使得不带根的所有子树内部颜色都相同;
思路:
如果存在两个颜色不一样的连在一起,根就是他们两个中间一个。。。。。。直接搜两次就好了。。。
#include<bits/stdc++.h> using namespace::std; typedef pair<int,int> PII; const int N = 4e5+10; struct Edge{ int to; int next; }; Edge e[N]; int head[N],tol,n,col[N]; bool vis[N]; void add(int u,int v) { e[tol].to=v; e[tol].next=head[u]; head[u]=tol++; } void init() { tol=0; memset(head,-1,sizeof(head)); } bool ans; bool flat; void DFS(int u,int color) { vis[u]=true; if(!ans) return; for(int i=head[u];~i;i=e[i].next) { int v=e[i].to; if(vis[v]) continue; vis[v]=true; if(col[v]!=color){ ans=false; return; } DFS(v,color); } } bool Judge(int x) { ans=true; for(int i=1;i<=n;i++) vis[i]=false; vis[x]=true; for(int i=head[x];~i;i=e[i].next) { int v=e[i].to; DFS(v,col[v]); if(!ans) return false; } return true; } int solve(int x) { int v; bool flag=false; for(int i=head[x];~i;i=e[i].next) { v=e[i].to; if(col[v]!=col[x]) { flag=true; return v; } } return -1; } int main() { int u,v; scanf("%d",&n); init(); for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(int i=1;i<=n;i++) scanf("%d",&col[i]); flat=false; for(int i=1;i<=n;i++) { int j; j=solve(i); if(j!=-1) { if(Judge(j)) { puts("YES"); printf("%d ",j); } else if(Judge(i)) { puts("YES"); printf("%d ",i); } else puts("NO"); return 0; } } puts("YES"); puts("1"); return 0; }