树形DP(Holiday's Accommodation HDU4118)
题意:有n间房子,之间有n-1条道路连接,每个房间里住着一个人,这n个人都想到其他房间居住,并且每个房间不能有两个人,问所有人的路径之和最大是多少?
分析:对于每条边来说,经过改边的人由该边两端元素个数较小者决定
#pragma comment(linker, "/STACK:1024000000,1024000000") #include"stdio.h" #include"string.h" #include"queue" #define M 100009 using namespace std; struct node { int u,v,next; __int64 w; }edge[M*2]; int t,head[M],num[M],n; __int64 belong[M*2]; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,__int64 w) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].next=head[u]; head[u]=t++; } void dfs(int u,int f) { num[u]=1; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].v; if(v==f)continue; dfs(v,u); num[u]+=num[v]; belong[i]=num[v]; belong[i^1]=n-num[v]; } } int main() { int Case,i,a,b,kk=1; __int64 c; scanf("%d",&Case); while(Case--) { scanf("%d",&n); init(); for(i=1;i<n;i++) { scanf("%d%d%I64d",&a,&b,&c); add(a,b,c); add(b,a,c); } dfs(1,1); __int64 ans=0; for(i=0;i<t;i+=2) { ans+=2*edge[i].w*min(belong[i],belong[i^1]); } printf("Case #%d: %I64d\n",kk++,ans); } }