(最小生成树) hdu 4424

Conquer a New Region

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1382    Accepted Submission(s): 455

Problem Description

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

Source

2012 Asia ChangChun Regional Contest

题意:

给你一颗树,树中每条边有一权值c,对于从i节点到j节点的路径,其权值定义为该路径上边权值的最小值,于是问找到一个中心点,使得从该点到其他节点的路径权值和最大,求该最大值。

思路:

想到并查集这个数据结构,先对边从大到小排序,然后枚举边,合并点,将点A合并到B里面要满足以B的根节点为中心的权值比以A的根节点为中心的权值要大。

妈的。。。注意long long 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
using namespace std;
int n,fa[2000010],sum[2000010];
long long dist[2000010];
struct node
{
    int x,y,w;
}e[2000010];
int find(int x)
{
    return x==fa[x]?x:fa[x]=find(fa[x]);
}
bool cmp(node a,node b)
{
    return a.w>b.w;
}
void Union(int x,int y,int w)
{
    int fx,fy;
    fx=find(x),fy=find(y);
    if(fx!=fy)
    {
        long long x1=(long long)(dist[fx]+(long long)sum[fy]*w);
        long long x2=(long long)(dist[fy]+(long long)sum[fx]*w);
        if(x1>x2)
        {
            fa[fy]=fx;
            sum[fx]+=sum[fy];
            dist[fx]=x1;
        }
        else
        {
            fa[fx]=fy;
            sum[fy]+=sum[fx];
            dist[fy]=x2;
        }
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            fa[i]=i,sum[i]=1,dist[i]=0;
        for(int i=1;i<n;i++)
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
        sort(e+1,e+n,cmp);
        for(int i=1;i<n;i++)
            Union(e[i].x,e[i].y,e[i].w);
        cout<<dist[find(1)]<<endl;
    }
    return 0;
}

  

时间: 2024-10-07 23:41:51

(最小生成树) hdu 4424的相关文章

最小生成树 || HDU 1301 Jungle Roads

裸的最小生成树 输入很蓝瘦 **并查集 int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } 找到x在并查集里的根结点,如果两个端点在同一个集合内,find之后两个值就相等了 每次找到权值最小的端点不在同一集合的边 把两个集合合并 #include <iostream> #include <cstdio> #include <algorithm> using namespace std; int

hdu 4424 Conquer a New Region (并查集)

///题意:给出一棵树,树的边上都有边权值,求从一点出发的权值和最大,权值为从一点出去路径上边权的最小值 # include <stdio.h> # include <algorithm> # include <iostream> # include <string.h> using namespace std; # define MAX 200010 struct node { int u,v; int w; }; struct node a[MAX];

HDU 4424 Conquer a New Region 最大生成树

给你一颗树 每条边有一个权值 选择一个点为中心 定义S值为中心到其他n-1个点的路径上的最小边权 求所有点S值的和 从大到小排序 每次合并2棵树 设为A集合 B集合 设A集合的最大S值的和为sumA B集合为sumB 中心在A或者B现在加入A-B这条边使得2个集合连通 因为A-B这条边的权值小于等于AB集合里面边的权值 所以如果合并之后中心在A 那么sumA = sumA+B集合的点数*A-B这条边的权值 sumB = sumB+A集合的点数*A-B这条边的权值 2者取大 #include <c

HDU 4424 并查集

点击打开链接 题意:给n个城镇,然后每两个城镇的价值给出,但是u->v的价值是u->v这条路径上的最小值,问从任意一个点出发到其他位置的和的最大值 思路:因为限制条件是路径上的最小值,那么我们按价值排序,从大到小排,就可以避免这个问题了,然后利用并查集来完成,对于两个集合,左集合的价值总和为A,右集合的价值总和为B,现在有一条路径连接这两个集合,那么我们考虑的是将A合并到B还是将B合并到A,我们可以这么比较,连接这两个集合的路径肯定是目前最小的价值,如果A集合元素个数为Ai,那么将A合并到B则

最小生成树 hdu 1233 模板题

#include <bits/stdc++.h> using namespace std; const int maxn=1e4+7; int n,m,cot,sum; struct edge { int u,v,w; bool operator <(const edge &b)const{ return w<b.w; } }g[maxn]; int f[maxn]; int Find(int x) { return f[x]==x?x:f[x]=Find(f[x]); }

HDU 4081 Qin Shi Huang&#39;s National Road System 最小生成树

分析:http://www.cnblogs.com/wally/archive/2013/02/04/2892194.html 这个题就是多一个限制,就是求包含每条边的最小生成树,这个求出原始最小生成树然后查询就好了 然后预处理那个数组是O(n^2)的,这样总时间复杂度是O(n^2+m) 这是因为这个题n比较小,如果n大的时候,就需要路径查询了,比如LCA 或者树链剖分达到O(mlogn) #include <iostream> #include <algorithm> #incl

HDU 5624 KK&#39;s Reconstruction(最小生成树)

题目链接:点击打开链接 题意:n个城市, m条可以修建的路, 修每条路有一个费用, 要求修建路将n个城市全部联通,并且最大费用减去最小费用最小. 思路:枚举最小边, 然后重新求一遍最小生成树,复杂度m^2, 出的数据水了, 左边BC水过了.. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #inc

Hdu 3371 Connect the Cities(最小生成树)

地址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 其实就是最小生成树,但是这其中有值得注意的地方:就是重边.题目没有告诉你两个城市之间只有一条路可走,所以两个城市之间可能有多条路可以走. 举例: 输入可以包含 1 2 3  // 1到2的成本为3   1 2 5  //1到2的成本为5      因此此时应选成本较低的路. 然后,已经连通的城市之间的连通成本为0. 这题用G++提交得到984ms的反馈,用C++提交则得到484ms的反馈. 很想知

Hdu 1301 Jungle Roads (最小生成树)

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1301 很明显,这是一道“赤裸裸”的最小生成树的问题: 我这里采用了Kruskal算法,当然用Prim算法也一样可以解题. #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> using namespace std; typedef struct node{ int f