• 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 }
  • 相关阅读:
    Leetcode题目practice
    文件操作
    39个奇葩代码注释,拿走不谢
    Spring Boot 之配置导入,强大到不行!
    Git 的这个神技,学会爽歪歪~
    同事天天写垃圾代码,就没办法?
    for (;;) 与 while (true),哪个更快?
    Spring Boot 怎么打一个可执行 Jar 包?
    程序员真的是太太太太太太太太难了!
    面试官:new一个对象有哪两个过程?
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4430425.html
Copyright © 2020-2023  润新知