您的位置:首页 > 其它

POJ 1655 - Balancing Act

2014-04-30 21:36 239 查看
裸的树的重心,要注意的问题是此题的边并没有给出准确的父子拓扑关系,所以需要建双向的边,所以以后要看清题意做仔细分析。

可以知道一个结点的子树必定是 它的拓扑子树 和 根树去掉这个拓扑结点树本身,思路也就很明显了。

// poj1655 Balancing Act
#include <iostream>
#include <cstring>
#define NDEBUG

#ifndef NDEBUG
#include <cstdio>
#endif

#define MAXN    20005

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("poj1655.in", "r", stdin);
#endif // NDEBUG
int T;
for(cin >> T; T; --T) {
cin >> N;
memset(vis, 0, sizeof(vis));
memset(dp2, 0, sizeof(dp2));
memset(head, -1, sizeof(head)), eptr = 0;
int i, j, root;
root = 0;
for(i=0; i<N-1; ++i) {
int k;
cin >> 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;
cout << j+1 << ' ' << dp[j] << endl;
}
return 0;
}


提交记录:

Accepted1292K610MSG++1269B2014-04-30 21:28:41
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: