• AtCoder NIKKEI Programming Contest 2019 E. Weights on Vertices and Edges (并查集)


    题目链接:https://atcoder.jp/contests/nikkei2019-qual/tasks/nikkei2019_qual_e

    题意:给出一个 n 个点 m 条边的无向图,每个点和每条边都有权值,让你删除一些边,使得最终的图中满足条件:一条边存在当且仅当包含该边的连通块的点权值和大于等于该边权值,问最少要移走多少条边。

    题解:删边不好做,考虑加边,对于每条边,判断加入是否合法。按边权从小到大排序进行加边,要加入一条边之前,若之前两点不连通,则合并起来变成一个连通块,可以用并查集来维护。存在一种情况,加入一些新的边之后,连通块权值增加,之前不能加入的边现在可以加入了,所以要记录之前连通块中已经加入的边的数量和全部边的数量以及最大的边权,便可以计算可以加入的边的数量。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 #define mst(a,b) memset((a),(b),sizeof(a))
     6 #define mp(a,b) make_pair(a,b)
     7 #define pi acos(-1)
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 #define lowbit(x) ((x)&(-x))
    11 const int INF = 0x3f3f3f3f;
    12 const double eps = 1e-6;
    13 const int maxn = 1e5 + 10;
    14 const int maxm = 1e6 + 10;
    15 const ll mod =  998244353;
    16 
    17 int a[maxn],fa[maxn];
    18 
    19 struct edge {
    20     int u,v,w;
    21     bool operator < (const edge &x)const {
    22         return w < x.w;
    23     }
    24 }e[maxn];
    25 
    26 int findd(int x) {
    27     return x == fa[x] ? x : fa[x] = findd(fa[x]);
    28 }
    29 
    30 struct node {
    31     int num,mxedge,ok;
    32     ll sum;
    33 }blo[maxn];
    34 
    35 int main() {
    36 #ifdef local
    37     freopen("data.txt", "r", stdin);
    38 //    freopen("data.txt", "w", stdout);
    39 #endif
    40     int n,m;
    41     scanf("%d%d",&n,&m);
    42     for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    43     for(int i = 1; i <= m; i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    44     sort(e + 1, e + 1 + m);
    45     for(int i = 1; i <= n; i++) {
    46         fa[i] = i;
    47         blo[i].num = blo[i].mxedge = blo[i].ok = 0;
    48         blo[i].sum = a[i];
    49     }
    50     int ans = 0;
    51     for(int i = 1; i <= m; i++) {
    52         int u = e[i].u, v = e[i].v, w = e[i].w;
    53         int fu = findd(u), fv = findd(v);
    54         if(fu == fv) {
    55             blo[fu].num++;
    56             blo[fu].mxedge = max(blo[fu].mxedge, w);
    57         } else {
    58             fa[fv] = fu;
    59             blo[fu].num += blo[fv].num + 1;
    60             blo[fu].mxedge = max(max(blo[fu].mxedge, blo[fv].mxedge), w);
    61             blo[fu].sum += blo[fv].sum;
    62             blo[fu].ok += blo[fv].ok;
    63         }
    64 
    65         if(blo[fu].sum >= blo[fu].mxedge) {
    66             ans += blo[fu].num - blo[fu].ok;
    67             blo[fu].ok = blo[fu].num;
    68         }
    69     }
    70     printf("%d
    ",m - ans);
    71     return 0;
    72 }
  • 相关阅读:
    [转载]Shell十三问(入门与提高)
    [转载]FPGA学习步骤
    matlab设计切比雪夫低通滤波器
    累加器A与ACC区别
    [转载]3分钟设计滤波器
    [转载]卷积运算的实际意义
    [转载]CRC校验原理
    一个怂女婿的成长笔记【三】
    一个怂女婿的成长笔记【一】
    一个怂女婿的成长笔记【二】
  • 原文地址:https://www.cnblogs.com/scaulok/p/10328453.html
Copyright © 2020-2023  润新知