标签:style blog class c code ext
题意:给一棵树(每个节点是一个城市),每个节点上有一个人。每个人都要到另外一个城市,并且每个城市最后只能有一个人。问全局所有人旅行的最长的长度可以是多少。
解法:一定可以构造一种这样的情形:对于每条边,使得少的一边的所有人都到另一边去。这样就实现了每条边的最大化利用。一定是最优解。
代码:
/****************************************************** * 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-8 const 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; }
标签:style blog class c code ext
原文地址:http://blog.csdn.net/xiefubao/article/details/26494959