zoukankan      html  css  js  c++  java
  • POJ 3107

    本题与POJ 1655的区别是要把所有重心的点按顺序输出出来。

    // poj3107 Godfather
    #include <cstdio>
    #include <cstring>
    #define NDEBUG
    
    
    #define MAXN    50005
    
    using namespace std;
    
    int N;
    int edgefw[MAXN*2], edge[MAXN*2], head[MAXN], eptr;
    
    #define EI(j, k)    ({ 
        edge[eptr] = k, edgefw[eptr] = head[j];    
        head[j] = eptr++;    
    })
    
    int dp[MAXN], dp2[MAXN];
    char vis[MAXN];
    
    void dfs(int i)
    {
        vis[i] = 1;
        int p, maxk = 0, sumn = 1;
        for(p = head[i]; p>=0; p = edgefw[p]) {
            int t = edge[p];
            if (!vis[t]) {
                if (!dp2[t]) dfs(t);
                sumn += dp2[t];
                if (maxk < dp2[t])
                        maxk = dp2[t];
            }
        }
        if (sumn != N && N - sumn > maxk) maxk = N - sumn;
        dp[i] = maxk, dp2[i] = sumn;
    }
    
    int main(void)
    {
        #ifndef NDEBUG
        freopen("poj3107.in", "r", stdin);
        #endif // NDEBUG
        scanf("%d", &N);
        memset(head, -1, sizeof(int) * N), eptr = 0;
        int i, j, root;
        root = 0;
        for(i=1; i<N; ++i) {
            int k;
            scanf("%d%d", &j, &k);
            --j,--k; EI(j, k), EI(k, j);
            if (root == k) root = j;
        }
        dfs(root);
        j = 0;
        for(i = 1; i < N; ++i)
            if (dp[i] < dp[j])
                j = i;
        root = 0;
        for(i = 0; i < N; ++i)
            if (dp[i] == dp[j]) {
                printf("%d", ++i);
                break;
            }
        for(; i<N; ++i)
            if (dp[i] == dp[j])
                printf(" %d", i+1);
        putchar('
    ');
        return 0;
    }
    3107 Accepted 4104K 532MS G++ 1249B 2014-05-01 01:22:57

    5/3更新 求树的重心模板:

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 
     6 #define FOR(p,i,s,t) for(__typeof(p) i=s; i<t; ++i)
     7 #define REP(t,i,n)    FOR(t,i,0,n)
     8 
     9 #define ECH(it, A) for (__typeof(A.begin()) it=A.begin(); it != A.end(); ++it)
    10 #define RST(x,y) memset(x, y, sizeof(x))
    11 #define RST0(x)    RST(x,0)
    12 
    13 typedef int Vt, Lt;
    14 const __typeof(Vt) MAXV = 50005;
    15 
    16 #define MAXE    ((MAXV<<1) - 2)
    17 
    18 Vt Vefw[MAXE], Veh[MAXV], eptr = 0;
    19 struct Vedge {
    20     Vt t;
    21     Lt l;
    22     Vedge() {}
    23     Vedge(Vt _t): t(_t), l(1) {}
    24     Vedge(Vt _t, Lt _l): t(_t), l(_l) {}
    25     void attach(Vt s) {
    26         extern Vedge Vs[];
    27         memcpy(Vs + eptr, this, sizeof(Vedge));
    28         Vefw[eptr] = Veh[s]; Veh[s] = ++eptr;
    29     }
    30 };
    31 #define addedge(s,t,l) ({Vedge e(t,l); e.attach(s);})
    32 Vedge Vs[MAXE];
    33 Vt gcoref_tot;
    34 char gc_8[MAXV];
    35 Vt gc_maxk[MAXV], gc_sumn[MAXV];
    36 
    37 int gc_root;
    38 
    39 void gcoref(Vt i)
    40 {
    41     char _gc8;
    42     if (!(_gc8 = gc_8[i])) gc_8[i] = -1;    // 遍历去环
    43     Vt sumn = 1, maxk = 0;
    44     for(Vt e = Veh[i]; e; e = Vefw[e]) {
    45         Vt t = Vs[--e].t;
    46         if (!gc_8[t]) {
    47             gcoref(t);
    48             sumn += gc_sumn[t];
    49             if (maxk < gc_sumn[t])
    50                 maxk = gc_sumn[t];
    51         }
    52     }
    53     gc_8[i] = _gc8;                // gc_8还有其他用途
    54     if (gcoref_tot - sumn > maxk) maxk = gcoref_tot - sumn;
    55     gc_sumn[i] = sumn, gc_maxk[i] = maxk;
    56     if (gc_maxk[gc_root] > maxk) gc_root = i;
    57 }
    58 
    59 inline Vt gcore(Vt root)
    60 {
    61     gc_maxk[gc_root = root] = gcoref_tot;
    62     gcoref(root);
    63     return gc_root;
    64 }
    65 
    66 int N;
    67 
    68 // 本模板使用方式:  gcoref_tot = 实际节点数
    69 // gc_8 != 0, 该节点被剪掉(忽略),可以用来存储其他信息
    70 // addedge加边(注意针对 无根树 要加双向),gcore返回重心节点
    71 // gc_maxk里面存储所有节点的最大真子树的节点数.
    72 
    73 int main(void)
    74 {
    75 //    freopen("poj3107.txt", "r", stdin);
    76     scanf("%d", &N);
    77     Vt root = 0;
    78     REP(int, i, N-1) {
    79         Lt l;
    80         Vt s,t;
    81         scanf("%d%d", &s, &t); --s, --t;
    82         addedge(s,t,1), addedge(t,s,1);
    83         if (root == t) root = s;
    84     }
    85     gcoref_tot = N;
    86     root = gcore(root);
    87     Vt i;
    88     for(i = 0; i < N; ++i)
    89         if (gc_maxk[i] == gc_maxk[root]) {
    90             printf("%d", ++i);
    91             break;
    92         }
    93     for(; i<N; ++i)
    94         if (gc_maxk[i] == gc_maxk[root])
    95             printf(" %d", i+1);
    96     putchar('
    ');
    97     return 0;
    98 }
  • 相关阅读:
    点击弹出层以外的区域隐藏弹出层
    css3 animation 动画属性简介
    IdentityServer4 接入自己的用户体系
    分布式事务的实现
    微服务分布式数据管理的挑战
    微服务的数据自治
    SkyWalking 分布式追踪系统
    创建、改进和控制微服务API的版本和契约
    富领域模型和贫血领域模型
    cenos 安装git
  • 原文地址:https://www.cnblogs.com/e0e1e/p/poj_3107.html
Copyright © 2011-2022 走看看