Description
在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家
之间建设双向道路使得国家之间连通。但是每个国家的国王都很吝啬,他们只愿
意修建恰好 n – 1条双向道路。 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值。例如,在下图中,虚线所示道路两端分别有 2 个、4个国家,如果该道路长度为 1,则费用为1×|2 – 4|=2。图中圆圈里的数字表示国家的编号。
由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案的修建
费用难以用人工计算,国王们决定找人设计一个软件,对于给定的建造方案,计
算出所需要的费用。请你帮助国王们设计一个这样的软件。
Input
输入的第一行包含一个整数n,表示 W 星球上的国家的数量,国家从 1到n
编号。接下来 n – 1行描述道路建设情况,其中第 i 行包含三个整数ai、bi和ci,表
示第i 条双向道路修建在 ai与bi两个国家之间,长度为ci。
Output
输出一个整数,表示修建所有道路所需要的总费用。
Sample Input
6
1 2 1
1 3 1
1 4 2
6 3 1
5 2 1
Sample Output
20
Hint
n = 1,000,000 1≤ai, bi≤n
0 ≤ci≤ 10^6
题意:Σ(边的权值*abs(左边点的个数-右边点的个数))
题解:dfs处理 邻接表或vector存图
n个点n-1条边 找个任意点为根,dfs 得到以该点为子树的树的大小k
Σ(边的权值*abs(k-(n-k)))
n个点n-1条边 找个任意点为根,dfs 得到以该点为子树的树的大小k
Σ(边的权值*abs(k-(n-k)))
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #define ll long long 6 using namespace std; 7 struct node 8 { 9 int pre; 10 int to; 11 int w; 12 }N[2000040]; 13 int nedge=0; 14 int pre[1000020]; 15 int n; 16 int used[1000020]; 17 int s[1000020]; 18 ll ans=0; 19 void add(int a,int b,int c) 20 { 21 nedge++; 22 N[nedge].to=b; 23 N[nedge].w=c; 24 N[nedge].pre=pre[a]; 25 pre[a]=nedge; 26 } 27 int ab(int x) 28 { 29 if(x<0) 30 return -x; 31 return x; 32 } 33 void dfs(int xx) 34 { 35 s[xx]=1; 36 for(int i=pre[xx];i;i=N[i].pre) 37 { 38 if(!used[N[i].to]) 39 { 40 used[N[i].to]=1; 41 dfs(N[i].to); 42 s[xx]+=s[N[i].to]; 43 ans=ans+(ll)N[i].w*ab(s[N[i].to]-(n-s[N[i].to])); 44 //cout<<"!!!"<<N[i].w<<" "<<s[xx]<<" "<<n-s[xx]<<endl; 45 } 46 } 47 } 48 int aa,bb,cc; 49 int main() 50 { 51 while(scanf("%d",&n)!=EOF) 52 { 53 memset(used,0,sizeof(used)); 54 nedge=0; 55 ans=0; 56 memset(pre,0,sizeof(pre)); 57 memset(s,0,sizeof(s)); 58 for(int i=1;i<n;i++) 59 { 60 scanf("%d %d %d",&aa,&bb,&cc); 61 add(aa,bb,cc); 62 add(bb,aa,cc); 63 } 64 used[1]=1; 65 dfs(1); 66 printf("%lld\n",ans); 67 } 68 return 0; 69 }