Cut 'em all! CodeForces - 982C(dfs)

C. Cut 'em all!
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You're given a tree with nn vertices.

Your task is to determine the maximum possible number of edges that can be removed in such a way that all the remaining connected components will have even size.

Input

The first line contains an integer nn (1n1051≤n≤105) denoting the size of the tree.

The next n1n−1 lines contain two integers uuvv (1u,vn1≤u,v≤n) each, describing the vertices connected by the ii-th edge.

It's guaranteed that the given edges form a tree.

Output

Output a single integer kk — the maximum number of edges that can be removed to leave all connected components with even size, or 1−1if it is impossible to remove edges in order to satisfy this property.

Examples
input
Copy
4
2 4
4 1
3 1
output
Copy
1
input
Copy
3
1 2
1 3
output
Copy
-1
input
Copy
10
7 1
8 4
8 10
4 7
6 5
9 3
3 5
2 10
2 5
output
Copy
4
input
Copy
2
1 2
output
Copy
0
Note

In the first example you can remove the edge between vertices 11 and 44. The graph after that will have two connected components with two vertices in each.

In the second example you can't remove edges in such a way that all components have even number of vertices, so the answer is 1−1


题意:有一颗树,现在,你需要切掉一些边,使这颗树分成若干个节点为偶数的部分,问,最多能切掉几条边。不能切,输出-1。

思路:首先,只有节点数为偶数的才能分成若干个偶数的部分,所以节点数为奇数的就直接输出-1吧。如果是偶数的话,从任意一点进行dfs,dfs返回的是子树节点的个数,如果是偶数的话,那么,父节点与子树的这条边一定是可以切掉的,所以,只要记录子树节点为偶数的个数就可以了。

#include "iostream"
#include "vector"
#include "cstdio"
using namespace std;
const int Max=1e5+10;
vector<int > G[Max];
bool flag[Max];//避免重复计算
int ans;
int dfs(int x)
{
    int res=0;
    for(int i=0;i<G[x].size();i++){
        int v=G[x][i];
        if(!flag[v]){
            flag[v]=1;
            int tmp=dfs(v);
            if(tmp%2==0) ans++;//如果子树节点的个数是偶数,那么,这条边就可以切掉
            res+=tmp;
        }
    }
    return res+1;//子树节点加一,就是这颗树的节点数
}
int main()
{
    int n,u,v;
    ans=0;
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    if(n%2!=0)//如果节点数为奇数,那么一定不可以切边
        printf("-1\n");
    else{
        flag[1]=1;
        dfs(1);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41874469/article/details/80478642
今日推荐