codeforces 765E dfs
2017-02-15 19:46
316 查看
题意:每次从一棵树中找两根长度相同、起点相同的直链并删去其中一根。重复这个操作,求可以得到的最短直链的长度。需要注意的是树即使已经被删成直链了,如果长度是偶数还可以继续删的。
![](https://img-blog.csdn.net/20170215192741643?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV2VpR3Vhbl8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
问题的关键是找到树中的“特殊点”,也就是我上面的图中的所有红点。“特殊点”的特点是它的度>2,且与它相连的直链长度不全相等,即以它为起点,不经过其他度>2的点,到达叶子节点的路径有至少两条,且长度不全相等。
容易看出:若特殊点超过1个,结果必是-1;如果上述路径有三种及以上的长度,结果也是-1。不然,结果就是这两种长度之和,然后再除2直到不为偶数。
看出这个结论后就非常简单了:先对任一点建dfs树,用set存起每个点的节点的返回值,如果set.size>=3直接-1,如果==2就说明这个点是特殊点,再以这个点为起点建树做一遍。如果==1说明是普通点,直接+1返回上一层。
此外还需判断没有特殊点的情况。答案不一定直接就是cut(N-1),比如4 4 1 4 2 4 3这组数据,还得瞎搞一下,不再赘述。
问题的关键是找到树中的“特殊点”,也就是我上面的图中的所有红点。“特殊点”的特点是它的度>2,且与它相连的直链长度不全相等,即以它为起点,不经过其他度>2的点,到达叶子节点的路径有至少两条,且长度不全相等。
容易看出:若特殊点超过1个,结果必是-1;如果上述路径有三种及以上的长度,结果也是-1。不然,结果就是这两种长度之和,然后再除2直到不为偶数。
看出这个结论后就非常简单了:先对任一点建dfs树,用set存起每个点的节点的返回值,如果set.size>=3直接-1,如果==2就说明这个点是特殊点,再以这个点为起点建树做一遍。如果==1说明是普通点,直接+1返回上一层。
此外还需判断没有特殊点的情况。答案不一定直接就是cut(N-1),比如4 4 1 4 2 4 3这组数据,还得瞎搞一下,不再赘述。
#include<stdio.h> #include<vector> #include<set> const int maxn=200020; std::vector<int>edge[maxn]; int N,q; int cut(int t){ while(!(t&1))t>>=1; return t; } int dfs(int n,int pre){ int deg=edge .size(); if(deg==1)return 1; else if(deg==2)return 1+dfs((pre==edge [0])?edge [1]:edge [0],n); else{ std::set<int>s; for(int i=0;i<deg;i++)if(edge [i]!=pre) s.insert(dfs(edge [i],n)); if(s.size()==1)return *s.begin()+1; if(q)printf("-1\n"),exit(0); if(pre)q=1,s.insert(dfs(pre,n)); if(s.size()>=3)printf("-1\n"),exit(0); printf("%d\n",cut(*s.begin()+*s.rbegin())); exit(0); }; } int main(){ scanf("%d",&N); for(int i=1;i<N;i++){ scanf("%d%d",&u,&v); edge[u].push_back(v); edge[v].push_back(u); } for(int i=1;i<=N;i++)if(edge[i].size()>2) return 0*printf("%d",cut(dfs(i,0))); printf("%d",cut(N-1)); return 0; }
相关文章推荐
- CodeForces 509B Painting Pebbles
- codeforces 633B A Trivial Problem
- CodeForces 471C MUH and House of Cards
- Problem--50A--Codeforces--Domino piling
- Codeforces 839B
- CodeForces 919
- SEU寒假训练题解二 H Codeforces 435D
- Codeforces 632B Alice, Bob, Two Teams 【水题】
- CodeForces 697A Pineapple Incident(数列,水下题)
- 【CodeForces】500B - New Year Permutation(Floyd)(贪心)
- Codeforces 106 D. Treasure Island(前缀和预处理)
- Codeforces 920C Swap Adjacent Elements
- Second price auction - CodeForces 513 C 概率期望
- CodeForces 151A - Soft Drinking
- Codeforces 678E(Another Sith Tournament)
- Codeforces 359D 想法
- codeforces 24C 找规律
- CodeForces - 686D D. Kay and Snowflake
- CodeForces 274A k-Multiple Free Set
- Codeforces 626E Simple Skewness 「数学」「二分」