Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) E. Tree Folding 拓扑排序

E. Tree Folding

题目连接:

http://codeforces.com/contest/765/problem/E

Description

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 = v, a1, …, ak, and b0 = v, b1, …, bk. Additionally, vertices a1, …, ak, b1, …, 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 ≤ n, u ≠ 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.

Sample Input

6
1 2
2 3
2 4
4 5
1 6

Sample Output

3

Hint

题意

给你一棵树,可以在这棵树上进行若干次操作,每次操作可以把两条相同的链,根据一个中点合并在一起,具体看题目的图片(CF上面)

然后问你经过若干次合并之后,最后的最短链长度是多少。

如果不能合并成一条链,输出-1.

题解:

拓扑排序,每次我们从度数为1的点出发bfs。

然后往上合并,如果遇到交叉点,我们就合并链。

我们用一个set来合并就好了,如果两条链长度一样,在set里面自动就合并了。

显然能够bfs的点的set里面只有一个数。

而且只能有一个点的set里面有两个数。

最后扫一遍check一下就好了。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+7;
vector<int> E[maxn];
int n,vis[maxn],len[maxn],de[maxn],d[maxn];
set<int> S[maxn];
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        E[a].push_back(b);
        E[b].push_back(a);
        d[a]++;
        d[b]++;
    }
    queue<int> Q;
    for(int i=1;i<=n;i++){
        if(E[i].size()==1){
            Q.push(i);
            S[i].insert(0);
        }
    }
    while(!Q.empty()){
        int now = Q.front();
        vis[now]=1;
        Q.pop();
        for(int i=0;i<E[now].size();i++){
            int v = E[now][i];
            if(vis[v])continue;
            S[v].insert((*S[now].begin())+1);
            d[v]--;
            if(d[v]==1&&S[v].size()==1){
                Q.push(v);
            }
        }
    }
    int ans = 0,num2 = 0;
    for(int i=1;i<=n;i++){
        if(S[i].size()==0){
            cout<<"-1"<<endl;
            return 0;
        }
        if(S[i].size()>2){
            cout<<"-1"<<endl;
            return 0;
        }
        if(S[i].size()==1){
            ans=max(ans,*S[i].begin());
        }
        if(S[i].size()==2){
            ans=max(ans,*S[i].begin()+*S[i].rbegin());
            num2++;
        }
    }
    if(num2>1){
        cout<<"-1"<<endl;
        return 0;
    }
    while(ans%2==0){
        ans/=2;
    }
    cout<<ans<<endl;
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/6401615.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞