CodeForces 982 C Cut 'em all!

Cut 'em all!

题意:求删除了边之后,剩下的每一块联通块他的点数都为偶数,求删除的边最多能是多少。

题解:如果n为奇数,直接返回-1,因为不可能成立。如果n为偶数,随意找一个点DFS建树记录下他的子孙+本身的个数。然后再DFS一下,对于每一个点,他的个数为偶数,就把他与父节点的边隔断, cnt++。 最后cnt就是答案。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 1e5+10;
17 vector<int> son[N];
18 int ans = 0;
19 int cnt[N];
20 void dfs(int o, int u){
21     cnt[u] = 1;
22     for(int i = 0; i < son[u].size(); i++){
23         int v = son[u][i];
24         if(o == v) continue;
25         dfs(u,v);
26         cnt[u] += cnt[v];
27     }
28 }
29 void dfs2(int o, int u){
30     if(cnt[u]%2 == 0) ans++;
31     for(int i = 0; i < son[u].size(); i++){
32         int v = son[u][i];
33         if(o == v) continue;
34         dfs2(u,v);
35     }
36 
37 }
38 int main(){
39     ///Fopen;
40     int n, u, v;
41     scanf("%d", &n);
42     for(int i = 1; i < n; i++){
43         scanf("%d%d", &u, &v);
44         son[u].pb(v);
45         son[v].pb(u);
46         cnt[u]++;
47         cnt[v]++;
48     }
49     if(n&1){
50         printf("-1");
51         return 0;
52     }
53     dfs(1,1);
54     for(int i = 0; i < son[1].size(); i++)
55         dfs2(1,son[1][i]);
56     printf("%d", ans);
57     return 0;
58 }
View Code

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9055425.html
今日推荐