现在的位置: 首页 > 综合 > 正文

ZOJ3659——Conquer a New Region

2019年02月16日 ⁄ 综合 ⁄ 共 2388字 ⁄ 字号 评论关闭
ZOJ Problem Set - 3659
Conquer a New Region


Time Limit: 5 Seconds     
Memory Limit:
32768 KB


The wheel of the history rolling forward, our king conquered a new region in a distant continent.

There are N towns (numbered from 1 to N) in this region connected by several roads. It's confirmed that there is exact one route between any two towns. Traffic is important while controlled colonies are far away from the local country. We define the capacity
C(i, j) of a road indicating it is allowed to transport at most C(i, j) goods between town i and town j if there is a road between them. And for a route between i and j, we define a value S(i, j) indicating the maximum traffic capacity between i and j which
is equal to the minimum capacity of the roads on the route.

Our king wants to select a center town to restore his war-resources in which the total traffic capacities from the center to the other N - 1 towns is maximized. Now, you, the best programmer in the kingdom, should help our king to select this center.

Input

There are multiple test cases.

The first line of each case contains an integer N. (1 ≤ N ≤ 200,000)

The next N - 1 lines each contains three integers a, b, c indicating there is a road between town a and town b whose capacity is c. (1 ≤ a, b ≤ N, 1 ≤ c ≤ 100,000)

Output

For each test case, output an integer indicating the total traffic capacity of the chosen center town.

Sample Input

4
1 2 2
2 4 1
2 3 1
4
1 2 1
2 4 1
2 3 1

Sample Output

4
3

Contest: The 2012 ACM-ICPC Asia Changchun Regional Contest

如果不是时间限制,个人认为floyd也可以做,其他做法一开始没想到,虽然看到kuangbin博客里的写的是用并查集,但还是没什么想法,看了网上大牛的解释才明白,并查集实在太巧妙

我们把边按权从大到小排序,在合并两个集合的时候,这时候访问到的这条边的权值是最小的,然后进行判断,合并到哪一方更加合理,

例如集合x,y,rank数组表示集合里的元素个数,num数组表示没加入这条边以前每个集合里的total traffic capacity,

判断条件是 rank[x]*w + num[y] 和 rank[y]*w + num[x]的大小

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

using namespace std;

const int N=200010;
int father[N];
int rank[N];
long long num[N];
struct node
{
	int u,v;
	int weight;
}edge[N];

void init(int n)
{
	for(int i=1;i<=n;i++)
	{
		father[i]=-1;
		rank[i]=1;
		num[i]=0;
	}
}

int find(int x)
{
	if(father[x]==-1)
		return x;
	return father[x]=find(father[x]);
}

void merge(int a,int b,int weight)
{
	int x=find(a);
	int y=find(b);
	if(x!=y)
	{
		if(((long long)rank[y]*weight+num[x])>((long long)rank[x]*weight+num[y]))
		{
			father[y]=x;
			rank[x]+=rank[y];
			num[x]+=(long long)rank[y]*weight;
		}
		else
		{
			father[x]=y;
			rank[y]+=rank[x];
			num[y]+=(long long)rank[x]*weight;
		}
	}
}

int cmp(node a,node b)
{
	return a.weight > b.weight;
}

int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		init(n);
		for(int i=0;i<n-1;i++)
		{
			scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].weight);
		}
		sort(edge,edge+n-1,cmp);
		for(int i=0;i<n-1;i++)
		{
			int u=edge[i].u;
			int v=edge[i].v;
			merge(u,v,edge[i].weight);
		}
		printf("%lld\n",num[find(1)]);
	}
	return 0;
}

抱歉!评论已关闭.