您的位置:首页 > 其它

道路修建

2016-07-07 11:12 190 查看

道路修建

问题描述

现在在LJY星球上有 N 个城市。

LJY为了使各个国家的经济发展,决定在各个国家之间建设双向道路使得国家之间连通。

但是LJY很吝啬,只愿意修建恰好 n–1 条双向道路。

每条道路的修建都要付出一定的费用,这个费用等于道路长度乘以道路两端的国家个数之差的绝对值。

例如,在下图中,虚线所示道路两端分别有 2 个、4 个国家,如果该道路长度为 1,则费用为 1×|2–4|=2。

图中圆圈里的数字表示国家的编号。



由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案的修建费用难以用人工计算,LJY决定找人设计一个软件,对于给定的建造方案,计算出所需要的费用。

请你帮助LJY设计一个这样的软件。

输入

输入文件名为Road.in。

输入第一行为一个正整数 N,代表总的点数的个数。

下接 N−1 行,每行三个正整数 ai、bi、ci,代表有一条长度为 ci 的双向道路连接 ai 和 bi 两个国家之间。

输出

输出文件名为Road.txt。

输出一行一个正整数,为修建所有道路的总费用。

输入样例

6

1 2 1

1 3 1

1 4 2

6 3 1

5 2 1

输出样例

20

数据范围

对于 40% 的数据,N<=1000。

对于 70% 的数据,N<=100000。

对于 100% 的数据,N<=1000000。

不允许开开关。

Solution

首先无向图转有向图。

用 f[i] 表示 i 节点下方的点的数量(包括根节点)。

则 f[i]=1+∑f[child]

于是 ans=abs(n−2∗f[i])

Code

#include <iostream>
#include <cstdio>
#include <cstring>

#define LL long long
#define abs(x) ((x)>0?(x):(-1)*(x))

using namespace std;

int n,cnt;
LL ans;
int head[1000010],nxt[2000010],data[2000010],weight[2000010];
int f[1000010];
bool vis[1000010];

void add(int x,int y,int z){
nxt[cnt]=head[x];data[cnt]=y;weight[cnt]=z;head[x]=cnt++;
nxt[cnt]=head[y];data[cnt]=x;weight[cnt]=z;head[y]=cnt++;
}

void dfs(int now){
f[now]=vis[now]=1;
for(int i=head[now];i!=-1;i=nxt[i])if(!vis[data[i]]){
dfs(data[i]);
ans+=(LL)abs(2*(f[data[i]])-n)*weight[i];
f[now]+=f[data[i]];
}
}

inline void in(int &x){
x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
}

int main(){
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
memset(head,-1,sizeof head);
scanf("%d",&n);
for(int i=1;i<n;i++){
int a,b,c;
in(a),in(b),in(c);
add(a,b,c);
}
dfs(1);
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: