zoukankan      html  css  js  c++  java
  • BZOJ3712 PA2014Fiolki(kruskal重构树)

      对合并过程建树。然后只需要按照时间顺序考虑每个反应就行了,时间顺序根据lca的深度确定。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 200010
    #define M 500010
    #define ll long long
    int n,m,k,a[N],p[N<<1],fa[N<<1],f[N<<1][20],deep[N<<1],t=0;
    ll ans=0;
    struct data{int to,nxt;
    }edge[N<<1];
    struct data2{int x,y,lca,i;
    }q[M];
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    void dfs(int k)
    {
        for (int i=p[k];i;i=edge[i].nxt)
        {
            f[edge[i].to][0]=k;
            deep[edge[i].to]=deep[k]+1;
            dfs(edge[i].to);
        }
    }
    int lca(int x,int y)
    {
        if (deep[x]<deep[y]) swap(x,y);
        for (int j=19;~j;j--) if (deep[f[x][j]]>=deep[y]) x=f[x][j];
        if (x==y) return x;
        for (int j=19;~j;j--) if (f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j];
        return f[x][0];
    }
    bool cmp(const data2&a,const data2&b)
    {
        return deep[a.lca]>deep[b.lca]||deep[a.lca]==deep[b.lca]&&a.i<b.i; 
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3712.in","r",stdin);
        freopen("bzoj3712.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),k=read();
        for (int i=1;i<=n;i++) a[i]=read();
        for (int i=1;i<=n+m;i++) fa[i]=i;
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            int p=find(x),q=find(y);
            fa[p]=fa[q]=n+i;
            addedge(n+i,p),addedge(n+i,q);
        }
        for (int i=n+m;i;i--)
        if (!f[i][0]) f[i][0]=i,dfs(i);
        for (int j=1;j<20;j++)
            for (int i=1;i<=n+m;i++)
            f[i][j]=f[f[i][j-1]][j-1];
        for (int i=1;i<=k;i++)
        q[i].x=read(),q[i].y=read(),q[i].lca=lca(q[i].x,q[i].y),q[i].i=i;
        sort(q+1,q+k+1,cmp);
        for (int i=1;i<=k;i++)
        if (find(q[i].x)==find(q[i].y))
        {
            int x=min(a[q[i].x],a[q[i].y]);
            ans+=x<<1;a[q[i].x]-=x,a[q[i].y]-=x;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    freeswitch 对接IMS
    freeswitch对接北京移动IMS
    多台 FreeSWITCH 服务器级联
    FreeSWITCH代码分析
    软交换freeswitch系统概要和源代码分析初步
    SQL*Net message from client
    FreeSwitch下配置DID的方法
    FreeSWITCH实现多人来电思路
    SIP开源项目opensip,Freeswitch
    运行 FreeSWITCH
  • 原文地址:https://www.cnblogs.com/Gloid/p/9723219.html
Copyright © 2011-2022 走看看