题干:

Each New Year Timofey and his friends cut down a tree of n vertices and bring it home. After that they paint all the n its vertices, so that the i-th vertex gets color ci.

Now it's time for Timofey birthday, and his mother asked him to remove the tree. Timofey removes the tree in the following way: he takes some vertex in hands, while all the other vertices move down so that the tree becomes rooted at the chosen vertex. After that Timofey brings the tree to a trash can.

Timofey doesn't like it when many colors are mixing together. A subtree annoys him if there are vertices of different color in it. Timofey wants to find a vertex which he should take in hands so that there are no subtrees that annoy him. He doesn't consider the whole tree as a subtree since he can't see the color of the root vertex.

A subtree of some vertex is a subgraph containing that vertex and all its descendants.

Your task is to determine if there is a vertex, taking which in hands Timofey wouldn't be annoyed.

Input

The first line contains single integer n (2 ≤ n ≤ 105) — the number of vertices in the tree.

Each of the next n - 1 lines contains two integers u and v (1 ≤ u, v ≤ nu ≠ v), denoting there is an edge between vertices u and v. It is guaranteed that the given graph is a tree.

The next line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 105), denoting the colors of the vertices.

Output

Print "NO" in a single line, if Timofey can't take the tree in such a way that it doesn't annoy him.

Otherwise print "YES" in the first line. In the second line print the index of the vertex which Timofey should take in hands. If there are multiple answers, print any of them.

Examples

Input

4
1 2
2 3
3 4
1 2 1 1

Output

YES
2

Input

3
1 2
2 3
1 2 3

Output

YES
2

Input

4
1 2
2 3
3 4
1 2 1 2

Output

NO

题目大意:

给定一棵每个顶点都标记颜色的树(无根树),问能否从一个顶点出发(以他为根节点),使得它的子树都是一样颜色(不包括这个顶点本身的颜色)详见第二个样例。

题解:因条件要求,我们可以知道不同的颜色的顶点中其中一个必须是答案顶点,我们统计一下不同颜色顶点个数(设为m),和不同颜色顶点中顶点出现次数。最后如果有一个顶点出现次数等于m,那么这个顶点就是答案顶点。

解题报告:

思维题啊害死我、、、

第一反应子树,我擦dfs序吧?

第二反应不行啊总不能对每一个顶点建树吧?要不试试、、

第三反应woc超时了,,,

关于图论的问题,可以考虑cnt计数、、、这题sum表示每一条边中有多少条边是两节点颜色不一样的。如果正好和节点 i 的边数相同,那 i 就是答案。

AC代码:

#include<bits/stdc++.h>using namespace std;
const int MAX = 1e5 + 5 ;
int u[MAX],v[MAX],cnt[MAX],col[MAX];
int main()
{int n,sum=0;cin>>n;for(int i = 1; i<n; i++) {scanf("%d%d",&u[i],&v[i]);}for(int i = 1; i<=n; i++) {scanf("%d",&col[i]);}for(int i = 1; i<n; i++) {if(col[u[i]]!=col[v[i]]) {sum++;cnt[u[i]]++;cnt[v[i]]++;}}for(int i = 1; i<=n; i++) {if(cnt[i] == sum) {printf("YES\n%d\n",i);return 0 ;}}printf("NO\n");return 0 ;
}

dfs序超时代码:(刚开始是o(n)的注释掉那一部分,后来改成logn的线段树,但是还是超时,看来时间都花在dfs序上了)

#include<bits/stdc++.h>using namespace std;
const int MAX = 100000 +5;
const int INF = 0x3f3f3f3f;
int cnt,id;
int st[MAX],ed[MAX],col[MAX],q[MAX];
int head[MAX];
struct Edge{int to,ne;
}e[1000000 +  5];
struct TREE {int l,r;int maxx,minn;
} tree[MAX * 4];
void dfs(int x,int fa)
{q[++id]=x;st[x]=id;for(int i=head[x];i!=-1;i=e[i].ne)if(e[i].to!=fa)dfs(e[i].to,x);ed[x]=id;
}
void pushup(int cur) {tree[cur].maxx = max(tree[cur*2].maxx,tree[cur*2+1].maxx);tree[cur].minn = min(tree[cur*2].minn,tree[cur*2+1].minn);
}
void build(int l,int r,int cur) {tree[cur].l=l;tree[cur].r=r;if(l == r) {tree[cur].maxx = col[q[r]];tree[cur].minn = col[q[r]];return ;}int m = (l + r)/2;build(l,m,cur*2);build(m+1,r,cur*2+1);pushup(cur);
}
int qmax(int pl,int pr,int cur) {if(pl <= tree[cur].l && pr >= tree[cur].r) return tree[cur].maxx;int ll=0,rr=0;if(pl <= tree[cur*2].r) ll = qmax(pl,pr,cur*2);if(pr >= tree[cur*2+1].l) rr = qmax(pl,pr,cur*2+1);return max(rr,ll);
}
int qmin(int pl,int pr,int cur) {if(pl <= tree[cur].l && pr >= tree[cur].r) return tree[cur].minn;int ll=INF,rr=INF;if(pl <= tree[cur*2].r) ll = qmin(pl,pr,cur*2);if(pr >= tree[cur*2+1].l) rr = qmin(pl,pr,cur*2+1);return min(rr,ll);
}
void add(int u,int v) {e[++cnt].to = v;e[cnt].ne = head[u];head[u] = cnt;
}
int main()
{int n,u,v;scanf("%d",&n);memset(head,-1,sizeof head);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]);}//枚举每一个顶点int flag = 1; for(int i = 1; i<=n; i++) {id=0;dfs(i,i);flag = 1;build(1,n,1);for(int j = head[i]; j!=-1; j=e[j].ne) {int tmp = col[e[j].to];int maxx = qmax(st[e[j].to],ed[e[j].to],1);int minn = qmin(st[e[j].to],ed[e[j].to],1);if(maxx != tmp || minn != tmp) flag=0;
//          for(int k = st[e[j].to]; k<=ed[e[j].to]; k++) {
//              if(col[q[k]] != tmp) {
//                  flag=0;break;
//              }
//          }if(flag == 0) break;}if(flag == 1) {printf("YES\n");printf("%d\n",i);return 0;}}printf("NO\n");return 0 ;
}

或者用并查集缩图https://www.cnblogs.com/jasonlixuetao/p/6401831.html

并查集思路:
先建图,遍历每个结点,统计每个结点的度,对结点i,若其相邻的结点j与其颜色相同,那么将其合并,并将结点i和结点j的度都减1
,合并完后,所有颜色相同且相互邻接的点合并为一个集合,统计集合个数cnt,将一个集合看作一个点,在这个虚图中满足条件的点i
一定满足cnt-1==deg[i],在合并后的原图中所有点中寻找满足cnt-1==deg[i]的点。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define N 100005
struct Node {int p,d;
} deg[N];
vector<int> gra[N];
int col[N];
bool cmp(Node a,Node b) {return a.d<b.d;
}
int father[N];
int wei[N];
int Find(int a) {if(father[a]!=a)father[a]=Find(father[a]);return father[a];
}
void Merge(int a,int b) {int fa=Find(a);int fb=Find(b);if(fa!=fb) {father[fa]=fb;wei[fb]+=wei[fa];}
}
int main() {int n;scanf("%d",&n);int a,b;for(int i=1; i<=n; i++) {deg[i].p=i;father[i]=i;wei[i]=1;}for(int i=0; i<n-1; i++) {scanf("%d%d",&a,&b);deg[a].d++;deg[b].d++;gra[a].push_back(b);gra[b].push_back(a);}for(int i=1; i<=n; i++)scanf("%d",&col[i]);for(int i=1; i<=n; i++)for(int j=0; j<gra[i].size(); j++) {if(col[i]==col[gra[i][j]]) {if(Find(i)!=Find(gra[i][j])) {Merge(i,gra[i][j]);deg[i].d--;deg[gra[i][j]].d--;}}}int cnt=0;for(int i=1; i<=n; i++)if(father[i]==i)cnt++;for(int i=1; i<=n; i++) {if(cnt==deg[i].d+1) {printf("YES\n%d\n",i);return 0;}}printf("NO\n");return 0;
}

☆【CodeForces - 764C】Timofey and a tree (思维题,树的性质)相关推荐

  1. codeforces The Artful Expedient(数学思维题)

    题目链接: http://codeforces.com/contest/869/problem/A 题目大意: 给你一个n,分别输入两组n个数字,如果这两组数字两两异或的结果与两组数字中的某一个数字相 ...

  2. CodeForces 104B-Testing Pants for Sadness(思维题)

    The average miner Vaganych took refresher courses. As soon as a miner completes the courses, he shou ...

  3. hdu5775(思维题树状数组)

    通过分析可得一个点它最右边的位置就是他现在的位置加上他后面的比他小的数字的个数. 一个点最左边的位置就是他开始的位置或者排完序以后的位置min(i,num[i]); 用数组数组从后往前可以巧妙的维护一 ...

  4. 【CodeForces - 789D】Weird journey(思维,图的性质,tricks,有坑)

    题干: Little boy Igor wants to become a traveller. At first, he decided to visit all the cities of his ...

  5. Codeforces 1077B Disturbed People(思维题)

    Codeforces 1077B Disturbed People(思维题) There is a house with nn flats situated on the main street of ...

  6. codeforces 有意思的思维题 1 ~ 15

    codeforces 思维题 1.给定数组,求满足i < j and ai * aj = i + j的数对数量 2.第 i 步向前跳 i 步或后退 1 步 3.给两个点,求正方形的另两个点 4. ...

  7. Educational Codeforces Round 67 (Rated for Div. 2)(D思维题 线段树/E树形dp(换根dp) 二次扫描与换根法)

    心得 D写了个假算法被hack了wtcl- E据涛神说是二次扫描与换根法,看了看好像和树形dp差不多 F概率dp G费用流 回头再补 思路来源 马老师 归神 贤神等代码 http://www.mami ...

  8. CF--思维练习-- CodeForces - 215C - Crosses(思维题)

    ACM思维题训练集合 There is a board with a grid consisting of n rows and m columns, the rows are numbered fr ...

  9. CodeForces - 1102A(思维题)

    https://vjudge.net/problem/2135388/origin Describe You are given an integer sequence 1,2,-,n. You ha ...

最新文章

  1. 给模型加装饰器Java,装饰器设计模式
  2. 齐次坐标的理解(1)
  3. 今天不聊我这些啦,来聊聊我们这种外行对你们的了解吧
  4. 2、Reactive Extensions for .NET(译)
  5. qt5 中文乱码解决
  6. python爬取素材图片代码_基于Python爬取素材网站音频文件
  7. 纳税服务系统【角色与用户】
  8. SQLServer锁的机制
  9. 关系抽取、时间抽取,实践项目推荐
  10. 戴尔-EMC将至强Phi服务器与Tesla GPU纳入PowerEdge
  11. linux在python的虚拟环境下运行程序_在win10和linux上分别安装Python虚拟环境的方法步骤...
  12. mysql -h 日志打印_mysql日志
  13. iOS 编译百度地图静态库-合二为一
  14. unit 12 文档练习
  15. c语言详解  蔡勒(Zeller)公式计算某一天是星期几  极其方便
  16. 利用python进行游戏编程 pdf
  17. linux zip文件解压命令详解
  18. python 爬手机号_【Python爬虫】手机号网段爬虫
  19. leetcode LCP 02. 分式化简
  20. 计算机中 空间局限性(Spatial Locality)与时间局限性(Temporal Locality)

热门文章

  1. [区块链与密码学][王小云院士][部分PPT][20200507]
  2. mysql分布式一致性hash_分布式哈希一致性
  3. java菜单面板设置完能关闭_用Java创建一个屏幕外框架(或者:当所有应用程序窗口关闭时,如何避免Mac上的空白菜单)?...
  4. 用类,求三个数的最大数
  5. AD16画线时如何切换90°、45°、任意角度画线模式
  6. python脚本之家 包的创建和调用_python基础之包的导入和__init__.py的介绍
  7. python将整数逆序_python练手入门小项目:字符串的妙用
  8. 求序列最长不下降子序列_最长不下降子序列nlogn算法详解
  9. 清空缓存的命令_超详细的mysql数据库查询缓存原理解析、涉及命令、流程分析等...
  10. 浏览器获取设备信息_一条命令获取 IE 浏览器保存网站的账号和密码信息