• 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 }
  • 相关阅读:
    Springboot源码 bean的注册
    Vue源码之 watch
    Vue源码之 slot
    Vue computed 的嵌套
    Vue的子组件绑定的方法中传入自定义参数
    Vue源码之 Vue的生命周期
    Vue源码之-----computed
    Vue源码之----为什么Vue中Array的pop,push等方法可以reactive,而Array[0]='a'这样的方法不会reactive?
    ReSharper 8.1支持Visual Studio 2013的特色——超强滚动条
    Python开发环境Wing IDE使用教程:部分调试功能介绍
  • 原文地址:https://www.cnblogs.com/scaulok/p/10328453.html
Copyright © 2020-2023  润新知