zoukankan      html  css  js  c++  java
  • zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)

    题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值。

    用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边。 对于要加入的一条路,这条路连接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值大。如果让集合B加入集合A,就是让中心城市位于集合A,那么可以确定这两个集合合并之后的总权值为: A的权值总和+B的数量*当前这条路的权值。同样算出让集合B加入集合A的情况,取两者合并后权值大的进行合并。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 #define MOD 1000000007
    10 const double eps=1e-5;
    11 #define cl(a) memset(a,0,sizeof(a))
    12 #define ts printf("*****
    ");
    13 const int MAXN=200005;
    14 int n,m,tt;
    15 int F[MAXN];
    16 struct Edge
    17 {
    18     int a,b,c;
    19     void input()
    20     {
    21         scanf("%d%d%d",&a,&b,&c);
    22     }
    23 }edge[MAXN];
    24 int find(int x)
    25 {
    26     if(F[x]==-1)    return x;
    27     return F[x]=find(F[x]);
    28 }
    29 struct Node
    30 {
    31     long long sum;
    32     long long num;
    33 }node[MAXN];
    34 bool cmp(Edge a,Edge b)
    35 {
    36     return a.c>b.c;
    37 }
    38 int main()
    39 {
    40     int i,j,k;
    41     #ifndef ONLINE_JUDGE
    42     freopen("1.in","r",stdin);
    43     #endif
    44     while(scanf("%d",&n)!=EOF)
    45     {
    46         for(i=1;i<n;i++)   edge[i].input();
    47         sort(edge+1,edge+n,cmp);
    48         for(i=1;i<=n;i++)
    49         {
    50             node[i].num=1;
    51             node[i].sum=0;
    52             F[i]=-1;
    53         }
    54         for(i=1;i<n;i++)
    55         {
    56             int a1=edge[i].a;
    57             int a2=edge[i].b;
    58             int t1=find(a1);
    59             int t2=find(a2);
    60             if(node[t1].sum+(long long)node[t2].num*edge[i].c<node[t2].sum+(long long)node[t1].num*edge[i].c)
    61             {
    62                 F[t1]=t2;   //t2作为被选择的点
    63                 node[t2].num+=node[t1].num;
    64                 node[t2].sum+=(long long)edge[i].c*node[t1].num;
    65             }
    66             else
    67             {
    68                 F[t2]=t1;
    69                 node[t1].num+=node[t2].num;
    70                 node[t1].sum+=(long long)edge[i].c*node[t2].num;
    71             }
    72         }
    73         printf("%lld
    ",node[find(1)].sum);
    74     }
    75 }
  • 相关阅读:
    [LA] 3027
    [POJ] 3264 Balanced Lineup [ST算法]
    [LA] 3644
    [Codeforces Round #248 (Div. 2)] B. Kuriyama Mirai's Stones
    [Codeforces Round #248 (Div. 2)] A. Kitahara Haruki's Gift
    [Codeforces Round #247 (Div. 2)] B. Shower Line
    [Codeforces Round #247 (Div. 2)] A. Black Square
    [UVA] 784
    [OpenJudge] 百练2754 八皇后
    449 Set、Map数据结构
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4430425.html
Copyright © 2011-2022 走看看