zoukankan      html  css  js  c++  java
  • 2020年HDU多校第二场 1001 Total Eclipse(思维)

    2020年HDU多校第二场 1001 Total Eclipse(思维)

    Total Eclipse

    题意:每次选一个连通块使里面所有点的值减一,当某个点减为零时其点连的所有边都会删去,求多少次操作使所有点变成0。

    题解:这个题感觉还是比较难想的,比赛时想了2个多小时也没想到;

    先给个样例:

    1

    3 2

    1 2 3

    3 1

    1 2

    可以将图画成柱形图(关系复杂的图不好画,这里是方便理解):

    显然答案为4,高度为一,切1刀,剩一个2与1不连通一共切3刀,共四次,那么我们是不是也可以反过来想,我将3号最上面切一刀与2等高,将3与2分别再切一刀与1等高,此时1将3与2连通,再一起切一刀。那么反过来想的好处是什么呢,正推是原本连通的点将不连通,要花o(n)时间重新建图,而反推,连通的点继续连通,新加进来的点可能将更多点连通,具有单调性,即可以优化大量时间,怎么记录连通关系啥的就不多说了,并查集搞一搞,cnt记录一下连通块数量既可

    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define ll long long
    ll to,t,n,m,u,v,fa[100007],vis[100007],cnt,h,ans,lin;
    struct madoka{
        ll p;
        ll h;
    }a[100007],now;
    ll fin(ll p){
        if(p==fa[p])return p;
        else{
            return fa[p]=fin(fa[p]);
        }
    }
    bool cmp(madoka a1,madoka a2){
        return a1.h>a2.h;
    }
    vector<int>ho[100007];
    void init(){
        for(int i=1;i<=n;i++)ho[i].clear(),vis[i]=0;
    }
    int main(){
        scanf("%lld",&t);
        while(t--){
            scanf("%lld%lld",&n,&m);
            init();
            for(int i=1;i<=n;i++){
                scanf("%lld",&a[i].h);
                a[i].p=i;
                fa[i]=i;
            }
            for(int i=1;i<=m;i++){
                scanf("%lld%lld",&u,&v);
                ho[u].push_back(v);
                ho[v].push_back(u);
            }
            sort(a+1,a+1+n,cmp);
            h=a[1].h;
            vis[a[1].p]=1;
            cnt=1;
            ans=0;
            for(int i=2;i<=n;i++){
                now=a[i];
                lin=(h-a[i].h);
                ans=(ans+lin*cnt);
                for(int j=0;j<ho[now.p].size();j++){
                    to=ho[now.p][j];
                    if(fin(now.p)!=fin(to)&&vis[to]){
                        cnt--;
                        fa[fin(now.p)]=fin(to);
                    }
                }
                vis[now.p]=1;
                h=a[i].h;
                cnt++;
            }
            ans=(ans+h*cnt);
            printf("%lld
    ",ans);
        }
    }
    
  • 相关阅读:
    HDU 1075 What Are You Talking About(字典树)
    HDU 1075 What Are You Talking About (stl之map映射)
    HDU 1247 Hat’s Words(字典树活用)
    字典树HihoCoder
    HDU 1277全文检索(字典树)
    HDU 3294 Girls' research(manachar模板题)
    HDU 3294 Girls' research(manachar模板题)
    HDU 4763 Theme Section(KMP灵活应用)
    Ordering Tasks UVA
    Abbott's Revenge UVA
  • 原文地址:https://www.cnblogs.com/whitelily/p/13372615.html
Copyright © 2011-2022 走看看