zoukankan      html  css  js  c++  java
  • 【推导】Codeforces Round #484 (Div. 2) C. Cut 'em all!

    题意:给你一棵树,让你切掉尽可能多的边,使得产生的所有连通块都有偶数个结点。

    对于一棵子树,如果它有奇数个结点,你再从里面怎么抠掉偶数结点的连通块,它都不会变得合法。如果它本来就有偶数个结点,那么你怎么抠,都是合法的。

    所以,我们只需要切断所有有偶数结点的子树的父边即可。

    然后再判一遍最后是否仍是合法的。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n;
    int e,first[100005],nex[200005],v[200005];
    void AddEdge(int U,int V){
    	v[e]=V;
    	nex[e]=first[U];
    	first[U]=e++;
    }
    bool vis[100005];
    bool cut[200005];
    int siz[100005];
    int ans;
    void dfs(int U,int kara){
    	siz[U]=1;
    	vis[U]=1;
    	for(int i=first[U];i!=-1;i=nex[i]){
    		if(!vis[v[i]]){
    			dfs(v[i],i);
    			siz[U]+=siz[v[i]];
    		}
    	}
    	if(kara!=-1 && siz[U]%2==0){
    		cut[kara]=cut[kara^1]=1;
    		++ans;
    	}
    }
    int cnt;
    void df2(int U){
    	vis[U]=1;
    	++cnt;
    	for(int i=first[U];i!=-1;i=nex[i]){
    		if(!vis[v[i]] && !cut[i]){
    			df2(v[i]);
    		}
    	}
    }
    int main(){
    	memset(first,-1,sizeof(first));
    	scanf("%d",&n);
    	int x,y;
    	for(int i=1;i<n;++i){
    		scanf("%d%d",&x,&y);
    		AddEdge(x,y);
    		AddEdge(y,x);
    	}
    	dfs(1,-1);
    	memset(vis,0,sizeof(vis));
    	for(int i=1;i<=n;++i){
    		if(!vis[i]){
    			cnt=0;
    			df2(i);
    			if(cnt%2==1){
    				puts("-1");
    				return 0;
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    ASCII码详解
    C#中判断上传类型为Excel,03和07版的链接字符串
    文本搜索工具的制作过程之搜索
    文本搜索工具之显示
    用C#实现十六进制字符串转换为ASCII
    7个秘诀 工作效率和薪水都翻倍
    C#委托
    VB的写法,关于版本写入注册表
    k8s 集群灾难恢复 k8s
    k8s 接合阿里云负载均衡 k8s
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/9055505.html
Copyright © 2011-2022 走看看