树形DP(Holiday's Accommodation HDU4118)

来源:互联网 发布:java大整数 编辑:程序博客网 时间:2024/05/21 10:29

题意:有n间房子,之间有n-1条道路连接,每个房间里住着一个人,这n个人都想到其他房间居住,并且每个房间不能有两个人,问所有人的路径之和最大是多少?

分析:对于每条边来说,经过改边的人由该边两端元素个数较小者决定

#pragma comment(linker, "/STACK:1024000000,1024000000")#include"stdio.h"#include"string.h"#include"queue"#define M 100009using 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);     }}



0 0