树形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
",kk++,ans);
     }
}






原文地址:https://www.cnblogs.com/mypsq/p/4348106.html