zoukankan      html  css  js  c++  java
  • Tree split (cut)

    Description


    There is an unrooted tree with (n) nodes, each node is numbered (1 sim n). Now it is required to delete one of the nodes so that the number of nodes in each subtree part that is divided does not exceed (n/2).

    Format


    Input

    The first line is a positive integer (t(≤5)), indicating the number of test data groups; in each group of data, the first line is a positive integer (n(≤10^5)), and the next (n-1) lines have two positive integers (x) and (y) ((x, y≤n)), respectively represent the two node numbers connecting the edges.

    Output

    For each group of data, output the number of the split point. If there are more than one node, output in the order from smallest to largest; if not, output "None".

    Sample


    Input

    2
    10
    1 2
    2 3
    3 4
    4 5
    6 7
    7 8
    8 9
    9 10
    3 8
    5
    1 5
    5 2
    3 4
    4 1
    

    Output

    3 8
    1
    

    Sample Explanation

    The tree of sample 1 is shown in the figure below, and nodes 3 and 8 meet the conditions:
    pic

    Sample Code


    #include <cstdio>
    #include <cstring>
    const int N=100010;
    struct Edge{
        int v, next;
    }edge[2*N]; 
    struct Head{
        int deg, mmax, first;
    }head[N];//deg记录以当前点为根的子树总结点数(度),mmax记录其子树中度的最大值 
    int now, n;
    bool vis[N];
    
    void in(int &s){
    	char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	for (s=0; c>='0' && c<='9'; c=getchar())
    		s=s*10+c-'0';
    }
    inline int mx(int a, int b){
    	return a>b ? a : b;
    }
    void ins(int x, int y){
    	now++; edge[now].v=y; 
    	edge[now].next=head[x].first; head[x].first=now;
    }//头插法建立链式前向星 
    
    void dfs(int r){
        vis[r]=1;
        int deg=1, tp=0;
        for (int k=head[r].first; k; k=edge[k].next){
            int v=edge[k].v;
            if (!vis[v]){
                dfs(v);
                if (head[v].deg > tp) 
                    tp=head[v].deg;
                deg+=head[v].deg;
            }
        }
        head[r].deg=deg;//记录当前子树的总结点数(度) 
        head[r].mmax=mx(tp, n-deg);//记录所有子树中的最大度 
    }
    int main(){
        freopen("cut.in", "r", stdin);
        freopen("cut.out", "w", stdout);
        int t;
        scanf("%d", &t);
        while (t--){
    		scanf("%d", &n);
            memset(vis, 0, sizeof(vis));
            memset(head, 0, sizeof(head));
    		int x, y;
            now=0;
            for (int i=1; i<n; i++){
                in(x), in(y);//scanf("%d %d", &x, &y); 
                ins(x, y); ins(y, x);
            }
            dfs(1); 
    		bool ok=false;
            for (int i=1; i<=n; i++)
                //if (n-head[i].deg <= n/2 && head[i].mmax <= n/2){
    			if (head[i].mmax <= n/2){
                    printf("%d ", i); ok=true;
                }//n-head[i].deg表示除去当前子树外其他所有结点总数(恰好构成另一个方向的子树) 
            if (!ok) printf("None");
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    构建之法第九章
    九周总结学习笔记
    第一阶段对各组评价
    冲刺二阶段第八天
    冲刺二阶段第七
    冲刺二阶段第六天
    冲刺二阶段第五天
    构建之法第八章
    冲刺二阶段第四天
    冲刺二阶段第三天
  • 原文地址:https://www.cnblogs.com/jiupinzhimaguan/p/13806447.html
Copyright © 2011-2022 走看看