bzoj1131: [POI2008]Sta

题目链接

bzoj1131: [POI2008]Sta

题解

树形dp,我们可以预处理以1为根子树大小与ans,然后就可以O1转移

代码

/*
我们可以预处理以1为根子树大小与ans,然后就可以O1转移 
*/
#include<cstdio> 
#include<cstring> 
#include<algorithm>
const int maxn = 1000007;  
#define int long long 
struct node { 
	 int v,next; 
} edge[maxn << 1]; 
int head[maxn],num = 0; 
inline void add_edge(int u,int v) { 
	edge[++ num].v = v;edge[num].next = head[u];head[u] = num; 
} 
int n,size[maxn],deep[maxn],sum[maxn] ; 
int ans = 0;   
void dfs(int x,int fa) { 
	size[x] = 1;  sum[x] = deep[x]; 
	for(int i = head[x];i;i = edge[i].next) { 
		//else top[edge[i].v] = top[x]; 
		if(edge[i].v != fa) { deep[edge[i].v] = deep[x] + 1; 
			dfs(edge[i].v,x); 
			sum[x] += sum[edge[i].v]; 
			size[x] += size[edge[i].v];  
		}	 
	} 
} 
int pos = 1; 
int dp[maxn]; 
void Dfs(int x,int fa) { 
	for(int i = head[x];i;i = edge[i].next) { 
		int v = edge[i].v; 
		if(v == fa)continue;  
		dp[v] = dp[x] - size[v] + n - size[v]; 
		if(dp[v] > ans || (dp[v] == ans && v < pos)) ans = dp[v],pos = v;
		Dfs(v,x); 
	} 
} 
main() { 
	scanf("%lld",&n); 
	for(int u,v,i = 1;i < n;++ i) { 
		 scanf("%lld%lld",&u,&v); 
		 add_edge(u,v);add_edge(v,u); 
	} 
	dfs(1,0); 
	dp[1] = ans = sum[1]; 
	Dfs(1,0); 
	printf("%lld\n",pos); 
	return 0;
} 
 
posted @ 2018-07-04 21:17  zzzzx  阅读(118)  评论(0编辑  收藏  举报