hdu4118(树形DP)

来源:互联网 发布:最好的防火墙软件 编辑:程序博客网 时间:2024/06/04 19:01

题意:给一棵树(每个节点是一个城市),每个节点上有一个人。每个人都要到另外一个城市,并且每个城市最后只能有一个人。问全局所有人旅行的最长的长度可以是多少。


解法:一定可以构造一种这样的情形:对于每条边,使得少的一边的所有人都到另一边去。这样就实现了每条边的最大化利用。一定是最优解。

代码:

/******************************************************* author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8const double pi=acos(-1.0);typedef long long LL;const int Max=100100;const int INF=1000000007;struct edge{    int u,v;    LL value;    int next;} edges[Max*2];bool rem[Max];int head[Max];LL num[Max];int tot=0;void addedge(int u,int v,int value){    edges[tot].u=u;    edges[tot].v=v;    edges[tot].value=value;    edges[tot].next=head[u];    head[u]=tot++;}int n;LL ans=0;void dfs(int k){    if(rem[k]) return ;    rem[k]=1;    num[k]=1;    for(int i=head[k];i!=-1;i=edges[i].next)    {        int t=edges[i].v;        if(rem[t])continue;        dfs(t);        ans+=min(num[t],n-num[t])*edges[i].value;        num[k]+=num[t];    }}int main(){  int t;cin>>t;int kk=1;  while(t--)  {      ans=0;      tot=0;      memset(head,-1,sizeof head);      memset(rem,0,sizeof rem);      scanf("%d",&n);      for(int i=0;i<n-1;i++)      {          int u,v,value;          scanf("%d%d%d",&u,&v,&value);          addedge(u,v,value);          addedge(v,u,value);      }      dfs(1);      printf("Case #%d: %I64d\n",kk++,ans*2);  }   return 0;}

0 0