zoukankan      html  css  js  c++  java
  • AIM Tech R3 div2 E Centroid

    思路很明显了,假设是点x,则看它的子树中是否有大于n/2的,如果有,则在该子树中剪去它可以剪的且小于n/2的,接到点x上。

    则统计出在以x点为根的子树中,它的各子树可以剪去的且小于n/2的最大子子树。对于除去以x为根的子树的其他部分,记为up,则同样地统计它的可以剪除的符合条件的子树,最后对每个点判断一下就可以了。

    代码如下::(额,想的时候对up的这个不知道怎么写~谢指导)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    //#include <bitset>
    using namespace std;
    
    const int MAXN = 400010;
    
    vector<int> t[MAXN];
    int par[MAXN], sz[MAXN], up[MAXN], dw[MAXN], n;
    
    void dfs_sz(int u, int parent){
    	par[u] = parent;
    	sz[u] = 1;
    	int size = t[u].size();
    	for(int i = 0; i< size; i++){
    		int v = t[u][i];
    		if(v == parent) continue;
    		dfs_sz(v, u);
    		sz[u] += sz[v];
    	}
    }
    
    void dfs_down(int u, int parent){
    	dw[u] = (sz[u] <= n/2 ? sz[u] : 0);
    	int size = t[u].size();	
    	for(int i = 0; i < size; i++){
    		int v = t[u][i];
    		if(v == parent) continue;
    		dfs_down(v, u);
    		dw[u] = max(dw[u], dw[v]);
    	}
    }
    
    void dfs_up(int u, int parent, int val){
    	up[u] = max((n - sz[u] <= n /2? n - sz[u]: 0), val);
    	int size = t[u].size();
    	
    	int mx0 = 0, mx1 = 0;
    	
    	for(int i = 0; i < size; i++){
    		int v = t[u][i];
    		if(v == parent) continue;
    		if(dw[v] >= mx0){
    			mx1 = mx0;
    			mx0 = dw[v];
    		}
    		else if(dw[v] >= mx1){
    			mx1 = dw[v];
    		}	
    	}
    	
    	for(int i = 0; i < size ; i++){
    		int v = t[u][i];
    		if(v == parent) continue;
    		dfs_up(v, u, max(up[u], (mx0 == dw[v]? mx1 : mx0 )));
    		
    	}
    	
    	
    }
    
    
    
    int main(){
    	
    	int u, v;
    	
    	scanf("%d", &n);
    	for(int i = 1; i< n; i++){
    		scanf("%d%d", &u, &v);
    		t[u].push_back(v);
    		t[v].push_back(u);
    	}
    	
    	dfs_sz(1, -1);
    	dfs_down(1, -1);
    	dfs_up(1, -1, 0);
    	
    	for(int i = 1; i <= n; i++){
    		int ans = 1;
    		int size = t[i].size();
    		for(int k = 0; k < size; k++){
    			int u = t[i][k];
    			if(u == par[i]){
    				if(n - sz[i] - up[i] > n/2)
    					ans = 0;
    			}
    			else {
    				if(sz[u] - dw[u] > n/ 2)
    					ans = 0;
    			}
    			
    		}
    		printf("%d", ans);
    		if(i == n) printf("
    ");
    		else printf(" ");
    		
    	}
    	
    	
    	
    	
    	return 0;
    }
    

      

  • 相关阅读:
    Hdu 5073 Galaxy 精度问题
    HDU 4435 charge-station (并查集)
    HDU-4689 Derangement
    HDU 1011 Starship Troopers
    python 冒泡、快速、归并排序
    Django 上下文管理器的应用
    Django ajax小例
    Django 上传文件
    Django 登录验证码
    Django 模型中的CRUD
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/5838717.html
Copyright © 2011-2022 走看看