zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 3:E (MST+树链剖分+RMQ)

    首先跑一边kruskal,以MST的边建树。

    若边在MST中则输出mincost

    否则新加入的边将构成环,则需要去掉MST中u->v路径上的w最大边

    询问也可用线段树,这里只需要维护最值,用RMQ编程复杂度低些(其实是懒

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"vector"
    #define ll long long
    
    using namespace std;
    const int MAXN = 200050;
    const int MAXE = 400050;
    const int INF = 0x3f3f3f3f;
    
    int f[MAXN],first[MAXN],mark[MAXE],top[MAXN],dep[MAXN],faa[MAXN],siz[MAXN],son[MAXN],id[MAXN],val[MAXN];
    ll dp[MAXN][20];
    int n,m,tot,cnt;
    ll cost,ans[MAXN];
    struct nod{
        int u,v,w,o;
    }E[MAXN];
    
    bool cmp(nod a,nod b){
        return a.w<b.w;
    }
    
    struct node{
        int e,next;
        node(){}
        node(int a,int b):e(a),next(b){}
    }edge[MAXN*2];
    
    int fa(int x){
        return x==f[x]?x:f[x]=fa(f[x]);
    }
    
    void init(){
        tot=0;
        cost=0;
        cnt=-1;
        for(int i=1;i<=m;i++) f[i]=i;
        memset(first,-1,sizeof(first));
        memset(mark,0,sizeof(mark));
        memset(son,-1,sizeof(son));
    }
    
    void mer(int a,int b){
        a=fa(a);
        b=fa(b);
        f[a]=b;
    }
    
    void addedge(int u,int v){
        edge[tot]=node(v,first[u]);
        first[u]=tot++;
        edge[tot]=node(u,first[v]);
        first[v]=tot++;
    }
    
    void kruskal(){
        for(int i=0;i<m;i++){
            if(fa(E[i].u)!=fa(E[i].v)){
                mer(E[i].u,E[i].v);
                cost+=(ll)E[i].w;
                addedge(E[i].u,E[i].v);
                mark[i]=1;
            }
        }
    }
    
    void dfs1(int u,int pre,int depth){
        siz[u]=1;
        dep[u]=depth;
        faa[u]=pre;
        for(int i=first[u];i!=-1;i=edge[i].next){
            int v=edge[i].e;
            if(v==pre) continue;
            dfs1(v,u,depth+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v]) son[u]=v;
        }
    }
    
    void dfs2(int u,int tp){
        top[u]=tp;
        id[u]=cnt++;
        if(son[u]==-1) return;
        dfs2(son[u],tp);
        for(int i=first[u];i!=-1;i=edge[i].next){
            int v=edge[i].e;
            if(v==faa[u]||v==son[u]) continue;
            dfs2(v,v);
        }
    }
    
    int makermq(int N){
        for(int i=0;i<N;i++) dp[i][0]=val[i];
        for(int j=1;(1<<j)<=N;j++)
        for(int i=0;i+(1<<j)-1<N;i++) dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    
    ll query(int l,int r){
        int k=(int)(log((r-l+1)*1.0)/log(2.0));
        return max(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    
    ll findmax(int u,int v){
        int tu=top[u],tv=top[v];
        ll ans=-INF;
        while(tu!=tv){
            if(dep[tu]<dep[tv]){
                swap(tu,tv);
                swap(u,v);
            }
            ans=max(ans,query(id[tu],id[u]));
            u=faa[u];
            tu=top[u];
        }
        if(u==v) return ans;
        if(dep[u]>dep[v]) swap(u,v);
        return max(ans,query(id[son[u]],id[v]));
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        init();
        for(int i=0;i<m;i++) {
            scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);
            E[i].o=i;
        }
        sort(E,E+m,cmp);
        kruskal();
        dfs1(1,0,1);
        dfs2(1,1);
        for(int i=0;i<m;i++){
            if(!mark[i]) continue;
            if(dep[E[i].u]<dep[E[i].v]) swap(E[i].u,E[i].v);
            val[id[E[i].u]]=E[i].w;
        }
        makermq(n);
        for(int i=0;i<m;i++){
            if(mark[i]) ans[E[i].o]=cost;
            else{
                ll t=findmax(E[i].u,E[i].v);
                ans[E[i].o]=cost+(ll)(E[i].w-t);
            }
        }
        for(int i=0;i<m;i++) printf("%I64d
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    python3 bytes数据类型探讨
    字典
    列表及元组
    在py文件中设置文件头
    函数的作用域、global与nonlocal
    python中 的意义及用法
    int、bool和str
    while循环、格式化输出、运算符和编码初识
    python初认识、基础数据类型以及 if 流程控制
    列表遍历和生成器遍历效率对比
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5064986.html
Copyright © 2011-2022 走看看