• The Child and Zoo 题解


    题目描述

    Of course our child likes walking in a zoo. The zoo has n areas, that are numbered from 1 to n. The i-th area contains ai animals in it. Also there are m roads in the zoo, and each road connects two distinct areas. Naturally the zoo is connected, so you can reach any area of the zoo from any other area using the roads.

    Our child is very smart. Imagine the child want to go from area p to area q. Firstly he considers all the simple routes from p to q. For each route the child writes down the number, that is equal to the minimum number of animals among the route areas. Let's denote the largest of the written numbers as f(p, q). Finally, the child chooses one of the routes for which he writes down the value f(p, q).

    After the child has visited the zoo, he thinks about the question: what is the sum of f(p, q) for all pairs p, q (p ≠ q)? Can you answer his question?

    对于一张图我们定义一个快乐值为f(p,q)为p到q的简单路径上最小点权值的最大值,求出所有f(p,q)(p != q)的和。(CF437D是求的平均值, 需要在此基础上除以一个(n(n-1)))

    输入输出格式

    输入格式:

    The first line contains two integers n and m (2 ≤ n ≤ 10^5; 0 ≤ m ≤ 10^5). The second line contains n integers: a1, a2, ..., an (0 ≤ ai ≤ 10^5). Then follow m lines, each line contains two integers xi and yi (1 ≤ xi, yi ≤ n; xi ≠ yi), denoting the road between areas xi and yi.

    All roads are bidirectional, each pair of areas is connected by at most one road.

    第一行输入两个数n,m表示点数和边数

    第二行有n个数,表示每个点的权值

    第三行到第3 + m行每行有两个数,表示连个点之间有条边

    输出格式:

    Output a integer — the value of sum .

    一行一个整数,表示所有f(u, v)  (u != v)的和。

     


     

    题解

    由题目的描述我们可以知道我们所有要经过的路径一定是在该图的最大生成树上的,但是这道题没有边权只有点权,所以我们要定义两个点之间的边权w[u,v] = min(a[u],a[v]) (w[u, v]表示两点之间的边权,a[u]表示u的点权)。在有了这棵树之后,我们需要的就只是两个点之间的路径权值了。刚开始我想了n^2暴力枚举两个点,然后求LCA之后再求最短长度,但时间超了,于是我们考虑下述做法:

        我们在建立最小生成树的过程就是利用并查集将两个连通块连通的过程,因为树上两个点之间的路径是唯一的,所以连通两个连通块后有且只有这两个连通块之间的点连通了但不对连通块内部造成影响。而且我们是按从大到小的顺序去枚举的边, 所以这条新连接的树边一定是这两个连通块之间两点路径的开心值。于是我们只用在维护并查集的同时维护一下并查集的大小,然后根据乘法原理就可以解决了。

     

    代码

    #include <bits/stdc++.h>
     using namespace std;
     
     const int MAX = 1000005;
     int Father[MAX], size[MAX];
     
     inline int Get_Father(int x)
         {
             return Father[x] == x ? x : Father[x] = Get_Father(Father[x]);
         }
     
     struct Edge
     {
         int from, to, w;
     }edge[MAX];
     
     int a[MAX];
     
     bool comp(const Edge & a, const Edge & b)
         {
             return a.w > b.w;
         }
     
     int main()
     {
     //    freopen("zoo.in", "r", stdin);
     //    freopen("zoo.out", "w", stdout);
         int n, m;
         int x, y;
         scanf("%d%d", &n, &m);
         //printf("%d %d", n, m);
         for(register int i = 1; i <= n; ++ i)    scanf("%d", &a[i]), Father[i] = i, size[i] = 1;
         for(register int i = 1; i <= m; ++ i)
             {
                 scanf("%d%d", &x, &y);
                 edge[i].from = x, edge[i].to = y, edge[i].w = min(a[x], a[y]);
             }
         sort(edge + 1, edge + m+1, comp);
         int tot = 0; long long ans = 0;
         for(register int i = 1; i <= m; ++ i)
             {
                 if(tot == n - 1)    break;
                 x = Get_Father(edge[i].from), y = Get_Father(edge[i].to);
                 if(x == y)    continue;
                 ans = ans +(long long) size[x] * size[y] * edge[i].w;
                 size[x] += size[y];
                 Father[y] = x;
                 tot ++;
             }
         printf("%lld
    ", ans << 1);
         return 0;
     }    

     

  • 相关阅读:
    详解Windows注册表分析取证
    逻辑漏洞简单的分析
    文件解析漏洞汇总
    aspcms 这个靶场。。。
    WebBug靶场基础篇 — 03
    WebBug靶场基础篇 — 02
    WebBug靶场介绍篇 — 01
    漏洞挖掘中的常见的源码泄露
    PHP对象Object的概念
    从史上八大MySQL事故中学到的经验
  • 原文地址:https://www.cnblogs.com/2020pengxiyue/p/9307209.html
Copyright © 2020-2023  润新知