• 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 }
  • 相关阅读:
    系统架构精选
    【原】Windows下Nexus搭建Maven私服
    【转】SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    Windows 安装计算机系统的几种常用方法
    windows下Ruby开发环境搭建
    Redis 学习记录
    SQLServer 表数据与 Excel 中数据的互相复制
    【转】用JIRA管理你的项目
    用模板写插入排序-数组
    整数类型
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4430425.html
Copyright © 2020-2023  润新知