国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Codeforces Round #397 E. Tree Folding (樹形dp)

2019-11-08 02:20:22
字體:
供稿:網(wǎng)友

E. Tree Foldingtime limit per test2 secondsmemory limit per test512 megabytesinputstandard inputoutputstandard output

Vanya wants to minimize a tree. He can perform the following Operation multiple times: choose a vertex v, and two disjoint (except for v) paths of equal length a0?=?va1, ..., ak, and b0?=?vb1, ..., bk. Additionally, vertices a1, ..., akb1, ..., bk must not have any neighbours in the tree other than adjacent vertices of corresponding paths. After that, one of the paths may be merged into the other, that is, the vertices b1, ..., bk can be effectively erased:

Help Vanya determine if it possible to make the tree into a path via a sequence of described operations, and if the answer is positive, also determine the shortest length of such path.

Input

The first line of input contains the number of vertices n (2?≤?n?≤?2·105).

Next n?-?1 lines describe edges of the tree. Each of these lines contains two space-separated integers u and v (1?≤?u,?v?≤?nu?≠?v) — indices of endpoints of the corresponding edge. It is guaranteed that the given graph is a tree.

Output

If it is impossible to obtain a path, PRint -1. Otherwise, print the minimum number of edges in a possible path.

Examplesinput
61 22 32 44 51 6output
3input
71 21 33 41 55 66 7output
-1Note

In the first sample case, a path of three edges is obtained after merging paths 2?-?1?-?6 and 2?-?4?-?5.

It is impossible to perform any operation in the second sample case. For example, it is impossible to merge paths 1?-?3?-?4 and 1?-?5?-?6, since vertex 6 additionally has a neighbour 7 that is not present in the corresponding path.

題意:

給你一棵樹,你可以在這棵樹上進(jìn)行若干次操作,每次操作可以把兩條相同的鏈,根據(jù)一個中點合并在一起,然后問你經(jīng)過若干次合并之后,最后的最短鏈長度是多少。如果不能合并成一條鏈,輸出-1。

題解:

樹形dp。

從節(jié)點1開始dfs,用set去保存一個節(jié)點有多少種深度的子樹。

那么,對于每一個節(jié)點:

1. 如果s.size()==0,那么當(dāng)前節(jié)點就是沒有子樹,也就是這個節(jié)點就是一條鏈中的一個端點,那就是不能縮成一條鏈啦。

2. 如果s.size()==1,那么當(dāng)前的節(jié)點有且只有一種深度的子樹,那么就可以將此時的所有子樹合成一棵樹。這條鏈的長度就是當(dāng)前的深度咯。

3.如果s.size()==2,并且fa==0即沒有父親時,那么我們就找到了一條鏈了,就把這2種深度加起來就是這條鏈的長度咯。

4.如果s.size()==2,并且fa!=0即有父親時,那么這條鏈就會多出父結(jié)點那部分,還沒搜完啊!這時我們要對當(dāng)前的節(jié)點再dfs一遍。

5.如果s.size()>2,當(dāng)前節(jié)點有3種深度的子樹?這時無解啊,直接輸出-1就可以了。

6.如果最終鏈的長度是偶數(shù),肯定不是最短啦,那么我們要考慮在最中間的那個點作為根,再將兩側(cè)的單鏈繼續(xù)合并。直到最短鏈的長度為奇數(shù)為止。

AC代碼:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 2e5 + 10;vector<int> G[N];int root;int dfs(int cur, int fa){    set<int>s;    for(auto v: G[cur])    {    	if(v!=fa){    		int tmp = dfs(v,cur);    		if(tmp==-1)return -1;    		else s.insert(tmp+1);		}	}	if(s.size() == 0) return 0;	else if(s.size() == 1) return *s.begin();	else if(s.size() == 2 && fa == 0) return *s.begin()+*s.rbegin();	else if(s.size()==2 && fa!=0)	{		root = cur;		return -1;	}	else if(s.size()>2)return -1;}int main(){    int n, u, v;    cin >> n;    for (int i = 0; i<n-1; i++){        cin >> u >> v;        G[u].push_back(v);        G[v].push_back(u);    }   int ans= dfs(1,0);   if(ans==-1 && root) ans = dfs(root,0);   while(ans%2==0){   	ans/=2;   }   return 0*printf("%d/n",ans);}/*61 22 32 44 51 631111 96 77 18 115 63 59 310 82 44 105*/


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 龙门县| 元朗区| 普宁市| 都兰县| 宁化县| 盘锦市| 南昌县| 西充县| 伊金霍洛旗| 融水| 黄冈市| 大理市| 闽侯县| 五指山市| 乌拉特前旗| 斗六市| 宁晋县| 南漳县| 吉木萨尔县| 格尔木市| 宁陕县| 阜新| 汾西县| 康定县| 泾川县| 永兴县| 铜陵市| 马山县| 澎湖县| 阳谷县| 福州市| 射阳县| 赤水市| 昌吉市| 霍邱县| 张家口市| 浠水县| 北碚区| 南平市| 德安县| 大渡口区|