zoukankan      html  css  js  c++  java
  • bzoj3135: [Baltic2013]pipesd

    Description

    n个水库,m条管道。Jester会在某些管道中间凿开一个洞,让水流出来或者用水泵把水打进去。保证这个流速是偶数。对于一条管道(u, v),如果在中间凿开了一个洞让水流出来,流速是2d m^3/s,那么水库uv失水速度为d m^3/s。同理,如果往一条管道(u, v)注水,流速为2p m^3/s,那么uv得到水的速度是p m^3/s

    给定图的构造以及每个水库的水流的变化,问每条边的方案是否唯一。

    Input

    第一行:水库数量n,管道数量m (1 <= n <= 100 000, 1 <= m <= 500 000)下面n行:第i个水库的变化速度ci (-10^9 <= ci <= 10^9)接下来m行:(u, v),保证没有重边

    Output

    如果方案唯一,输出方案,每行一个数xi-10^9 <= xi <= 10^9)表示第i条管道的流量变化。放水为负数,灌水为正数。否则输出0

    边看做未知数则每个点构成一个方程,保证有解,因此n<m时方案不唯一

    对于一个度为1的点,与其相邻的边的答案可以被确定,因此可以以此为突破口消元,若n=m-1则最后可以全部解出,若n=m则最后剩下一个环

    对于偶环,显然方案不唯一,对于奇环则可以简单地推出公式O(n)解出唯一解

    #include<cstdio>
    typedef long long i64;
    char buf[1000000],*ptr=buf,*pmx=buf+1000000;
    inline int g(){
        if(ptr==pmx)fread(ptr=buf,1,1000000,stdin);
        return *(ptr++);
    }
    int _(){
        int x=0,c=g(),f=1;
        while(c<48)c=='-'&&(f=-1),c=g();
        while(c>47)x=x*10+c-48,c=g();
        return x*f;
    }
    int n,m;
    int et[200007],enx[200007],e0[100007],ep=2,deg[100007],q[100007],ql=0,qr=0,v[100007],e[100007],p=0;
    i64 f[100007],ans[100007],s[100007];
    void dfs(int w,int pa){
        deg[w]=-1;
        v[++p]=w;
        for(int i=e0[w];i;i=enx[i]){
            int u=et[i];
            if(deg[u]==2)e[p]=i>>1,dfs(u,w);
            else if(u!=pa&°[u]==-1)e[p]=i>>1;
        }
    }
    int main(){
        n=_();m=_();
        if(m>n)return puts("0"),0;
        for(int i=1;i<=n;++i)f[i]=_();
        for(int i=0,a,b;i<m;++i){
            a=_();b=_();
            ++deg[a];++deg[b];
            et[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
            et[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
        }
        for(int i=1;i<=n;++i)if(deg[i]==1)q[++qr]=i;
        while(ql!=qr){
            int w=q[++ql];
            deg[w]=0;
            for(int i=e0[w];i;i=enx[i]){
                int u=et[i];
                if(!deg[u])continue;
                ans[i>>1]=f[w]*2;
                f[u]-=f[w];
                if(1==--deg[u])q[++qr]=u;
            }
        }
        for(int w=1;w<=n;++w)if(deg[w]==2){
            dfs(w,0);
            if(p%2==0)return puts("0"),0;
            v[p+1]=v[1];
            for(int i=1;i<=p;++i)s[i]=s[i-1]+(i&1?f[v[i+1]]:-f[v[i+1]]);
            for(int i=1;i<=p;++i)ans[e[i]]=(s[p]-s[i-1]*2)*(i&1?1:-1);
            break;
        }
        for(int i=1;i<=m;++i)printf("%lld
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    java读书笔记——this
    hdu1166树状数组
    从输入流中获取数据并以字节数组返回
    网易游戏2013年校招笔试题----货币面值
    flutter 获取当前系统时间,持续更新中
    flutter floatingActionButton悬浮按钮控件
    flutter 导航栏 BottomNavigationBar底部导航栏相当于iOS tabbar
    flutter的Scaffold,基本的纸墨布局
    flutter的Text,持续更新
    flutter中的=>表示什么
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6072968.html
Copyright © 2011-2022 走看看