题意:给n个点,每个点有一个人,有n-1条有权值的边,求所有人不在原来位置所移动的距离的和最大值。不能重复
这题的方法很有看点啊,标记为巩固题
Sample Input
1
4
1 2 3
2 3 2
4 3 2
Sample Output
Case #1: 18 //1去4,4去1,2去3,3去2
对于每条边,因为大家都想走的最远,那么相当于让边两端的人交换,花费就是 边长*经过边的人数
ans = Σ (每条路长 l )*(经过这条路的最大次数 f )
f = 2 * 这条边左边节点数和右边节点数最小值k. (这样左边的每一个点一定能够对应右边的某个点)
这个k可以dfs 求得.
hdu用c++交,g++会爆栈
1 #pragma comment(linker, "/STACK:10240000000000,10240000000000") 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iostream> 5 #include<string.h> 6 using namespace std; 7 const int MAXN=200010; 8 struct Node 9 { 10 int to,next; 11 int len; 12 }edge[MAXN*2]; 13 14 int head[MAXN]; 15 int tol; 16 int num[MAXN];//从这个点以下的结点数 17 long long ans; 18 void init() 19 { 20 tol=0; 21 memset(head,-1,sizeof(head)); 22 memset(num,0,sizeof(num)); 23 } 24 void add(int a,int b,int len) 25 { 26 edge[tol].to=b; 27 edge[tol].len=len; 28 edge[tol].next=head[a]; 29 head[a]=tol++; 30 31 edge[tol].to=a; 32 edge[tol].len=len; 33 edge[tol].next=head[b]; 34 head[b]=tol++; 35 } 36 int n; 37 //递归形式会超出内存 38 void dfs(int u,int pre) 39 { 40 for(int i=head[u];i!=-1;i=edge[i].next) 41 { 42 int v=edge[i].to; 43 if(v==pre)continue; 44 dfs(v,u); 45 num[u]+=num[v]; 46 ans+=(long long)edge[i].len*min(num[v],n-num[v]); 47 } 48 num[u]++; 49 } 50 51 /*int sta[MAXN]; 52 bool vis[MAXN]; 53 void dfs(int u) 54 { 55 memset(vis,false,sizeof(vis)); 56 int top=0; 57 sta[top++]=u; 58 vis[u]=true; 59 while(top>0) 60 { 61 bool flag=true; 62 int t=sta[top-1]; 63 for(int i=head[t];i!=-1;i=edge[i].next) 64 { 65 int v=edge[i].to; 66 if(vis[v])continue; 67 flag=false; 68 sta[top++]=v; 69 vis[v]=true; 70 } 71 if(!flag)continue; 72 top--; 73 for(int i=head[t];i!=-1;i=edge[i].next) 74 { 75 int v=edge[i].to; 76 if(num[v]!=0) 77 { 78 num[t]+=num[v]; 79 ans+=(long long)edge[i].len*min(num[v],n-num[v]); 80 } 81 } 82 num[t]++; 83 } 84 }*/ 85 86 int main() 87 { 88 int T; 89 int iCase=0; 90 int u,v,w; 91 #ifndef ONLINE_JUDGE 92 freopen("1.in","r",stdin); 93 #endif 94 scanf("%d",&T); 95 while(T--) 96 { 97 iCase++; 98 scanf("%d",&n); 99 init(); 100 ans=0; 101 for(int i=1;i<n;i++) 102 { 103 scanf("%d%d%d",&u,&v,&w); 104 add(u,v,w); 105 } 106 dfs(1,0); 107 printf("Case #%d: %I64d ",iCase,ans*2); 108 } 109 return 0; 110 }