CodeForces 982 C 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 }