[NOI2011]道路修建

题意

在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通。但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路。 每条道路的修建都要付出一定的费用,这个费用等于道路长度乘以道路两端 的国家个数之差的绝对值。例如,在下图中,虚线所示道路两端分别有 2 个、4 个国家,如果该道路长度为 1,则费用为 1×|2 – 4|=2。图中圆圈里的数字表示国 家的编号。

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

(n leq 10^6)

分析

照题目模拟就行了。

时间复杂度(O(n))

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read(T&x)
{
    T data=0;
	int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
		if(ch=='-')
			w=-1;
		ch=getchar();
	}
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=1e6+7;
int n;

struct Edge
{
	int nx,to,w;
}E[MAXN<<1];
int head[MAXN],ecnt;

void addedge(int x,int y,int w)
{
	E[++ecnt].to=y,E[ecnt].w=w;
	E[ecnt].nx=head[x],head[x]=ecnt;
}

ll ans;
int siz[MAXN];

void dfs(int x,int f)
{
	siz[x]=1;
	for(int i=head[x];i;i=E[i].nx)
	{
		int y=E[i].to,w=E[i].w;
		if(y==f)
			continue;
		dfs(y,x);
		siz[x]+=siz[y];
		ans += (ll) abs(n-2*siz[y]) * w;
	}
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
	read(n);
	for(int i=1;i<n;++i)
	{
		int x,y,w;
		read(x);read(y);read(w);
		addedge(x,y,w);
		addedge(y,x,w);
	}
	dfs(1,0);
	printf("%lld
",ans);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}
静渊以有谋,疏通而知事。
原文地址:https://www.cnblogs.com/autoint/p/9806895.html