zoukankan      html  css  js  c++  java
  • 【2020杭电多校第二场】Total Eclipse 思维+并查集

    Total Eclipse

    题意

    给出一个 n 个点,m 条边的无向图,每个顶点都有一个价值(b_i),你可以执行以下操作:

    选择一个连通块,处于这个连通块的所有顶点的价值减去 1 。

    问最少需要多少次操作,使得所有的顶点价值全部变为0。

    题解

    参考博客:hdu6763 Total Eclipse 2020杭电多校第2场

    我们每次从一个当前价值最小的顶点开始遍历,遍历到的顶点都减去该最小价值,如果某个顶点变为 0,那么就把这个点从图中抹去。直到所有顶点都被抹去。

    这样复杂度太高,无法接受。

    反着考虑:

    image-20200724211713419

    d 就是连通块的个数。

    代码

    /*
     * @Autor: valk
     * @Date: 2020-07-17 16:50:40
     * @LastEditTime: 2020-07-24 20:44:04
     * @Description: 你背叛了工人阶级,操 你 妈!
     */
    
    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    
    int fa[N],b[N],arr[N],vis[N],n,m;
    vector<int>vec[N],valk;
    bool cmp(int x,int y){
        return b[x]>b[y];
    }
    set<int>s;
    int find(int x){
        if(x==fa[x]){
            return x;
        }
        return fa[x]=find(fa[x]);
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            memset(vis,0,sizeof(vis));
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                vec[i].clear();
                scanf("%d",&b[i]);
                fa[i]=arr[i]=i;
            }
            for(int i=1,u,v;i<=m;i++){
                scanf("%d%d",&u,&v);
                vec[u].pb(v),vec[v].pb(u);
            }
            sort(arr+1,arr+1+n,cmp);
            ll ans=0;
            for(int i=1;i<=n;i++){
                vis[arr[i]]=1;
                s.clear(),valk.clear();
                int uu=find(arr[i]);
                for(int v:vec[arr[i]]){
                    if(vis[v]==0) continue;
                    int vv=find(v);
                    valk.pb(vv);
                    s.insert(vv);
                }
                for(int v:valk){
                    fa[v]=uu;
                }
                ans-=1LL*(s.size()-1)*b[arr[i]];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    /*
    100
    6 6
    3 4 5 2 3 6
    1 2
    2 3
    3 4
    4 5
    5 6
    6 1
    */
    
  • 相关阅读:
    最新pear安装
    php垃圾收集机制
    strstr的实现
    PHP 快速生成目录树
    php 去掉字符串
    php批量生成mysql触发器定义语句
    HTML的知识点讲解(HTML版本)
    mysql数据库怎么使用,mysql的使用方法
    sublime text3Emmet:HTML/CSS代码快速编写神器
    图片滚动插件jquery bxslider
  • 原文地址:https://www.cnblogs.com/valk3/p/13374637.html
Copyright © 2011-2022 走看看