POJ-1665 求树的重心 dfs

来源:互联网 发布:公知日杂什么意思 编辑:程序博客网 时间:2024/06/08 02:06

大家都很强,可与之共勉。

树的重心,就是取一个点,使得以这个点为根节点的max(子树的总结点数)最小。顾名思义,这就是一个树上的DP问题。在点分治里也要常常用到。

#include "cctype"#include "cstdio"#include "cstring"#define max(a, b)  ((a) > (b) ? (a) : (b))template<typename T>inline bool readIn(T &x)  {    x = 0;    T flag = 1;    char ch;    while( !isdigit(ch = (char) getchar()) )  if(ch == '-')  flag = -1;    x = ch - 48;    while( isdigit(ch = (char) getchar()) )        x = (x << 1) + (x << 3) + ch - 48;    x *= flag;    return true;}template<typename T>inline void write( T x )  {    if(x > 9)        write(x / 10);    putchar(x % 10 + 48);}template<typename T>inline bool writeIn(T x)  {    if(x < 0)  {        x = -x;        putchar('-');    }    write(x);    return true;}const int MAXN = (int) 20005;int head[MAXN], siz[MAXN], T, ne, u, v, n, G, Gsiz;struct edge  {    int to, pre;    edge(int to = 0, int pre = 0) : to(to), pre(pre)  { }} g[MAXN << 1];inline bool adde(int u, int v)  {    g[++ne] = edge(v, head[u]), head[u] = ne;    return true;}void dfs(int u, int f)  {    siz[u] = 1;    int maxsiz = 0;    for(int i = head[u]; i; i = g[i].pre)  {        int v = g[i].to;        if(v == f)  continue;        dfs(v, u);        siz[u] += siz[v];        maxsiz = max(maxsiz, siz[v]);    }    maxsiz = max(maxsiz, n - siz[u]);    if(maxsiz < Gsiz)        G = u, Gsiz = maxsiz;}int main()  {    readIn(T);    while(T--)  {        ne = 0;        readIn(n);        memset(head, 0 ,sizeof (int) * (n + 1));        Gsiz = 0x3f3f3f3f, G = 0;        for(register int i = 1; i < n; readIn(u), readIn(v), adde(u, v), adde(v, u), ++i);        dfs(1, -1);        writeIn(G);        putchar(' ');        writeIn(Gsiz);        putchar('\n');    }    return 0;}
0 0
原创粉丝点击