zoukankan      html  css  js  c++  java
  • zoj2314 无源汇上下界可行流

    题意:看是否有无源汇上下界可行流,如果有输出流量

    题解:对于每一条边u->v,上界high,下界low,来说,我们可以建立每条边流量为high-low,那么这样得到的流量可能会不守恒(流入量!=流出量),这时我们要想使得流量守恒,我们需要建立附加流,附加流 是在刚才的图上的改进流,对于每一个点如果有流入量(in)>流出量(out),那么对于多余的流入量,我们需要想办法新加一条边流量为in-out流入该点,反之如果in<out,那么需要建立一条边流量为out-in流出该点,我们此时可以建立一个超级源和超级汇,此时我们在附加流上跑一遍最大流,如果从超级源出发的所有流量等于最大流,也就是说能保证流量守恒,那么就是有可行流,每条边的可行流等于该边的轮流下界+附加流中的流过的流量(既附加流中反向边的流量)

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200+10,maxn=40000+10,inf=0x3f3f3f;
    
    struct edge{
        int from,to,Next,c,low;
    }e[maxn<<2];
    int cnt,head[N];
    int dis[N],s,t;
    int out[N],in[N];
    void add(int u,int v,int c,int low)
    {
        e[cnt].from=u;
        e[cnt].low=low;
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
        e[cnt].from=v;
        e[cnt].low=low;
        e[cnt].to=u;
        e[cnt].c=0;
        e[cnt].Next=head[v];
        head[v]=cnt++;
    }
    bool bfs()
    {
        memset(dis,-1,sizeof dis);
        dis[s]=0;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=head[x];~i;i=e[i].Next)
            {
                int te=e[i].to;
                if(e[i].c>0&&dis[te]==-1)
                {
                    dis[te]=dis[x]+1;
                    q.push(te);
                }
            }
        }
        return dis[t]!=-1;
    }
    int dfs(int x,int mx)
    {
        if(x==t)return mx;
        int flow=0;
        for(int i=head[x];~i;i=e[i].Next)
        {
            int te=e[i].to,f;
            if(dis[te]==dis[x]+1&&e[i].c>0&&(f=dfs(te,min(mx-flow,e[i].c))))
            {
                e[i].c-=f;
                e[i^1].c+=f;
                flow+=f;
            }
        }
        if(!flow)dis[x]=-2;
        return flow;
    }
    int maxflow()
    {
        int ans=0,f;
        while(bfs())
        {
            while((f=dfs(s,inf)))ans+=f;
        }
        return ans;
    }
    void init()
    {
        cnt=0;
        memset(head,-1,sizeof head);
        memset(out,0,sizeof out);
        memset(in,0,sizeof in);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int T;
        cin>>T;
        while(T--)
        {
            int n,m;
            cin>>n>>m;
            init();
            for(int i=0; i<m; i++)
            {
                int a,b,c,d;
                cin>>a>>b>>c>>d;
                out[a]+=c;
                in[b]+=c;
                add(a,b,d-c,c);
            }
            s=n+1,t=n+2;
            int sum=0;
            for(int i=1; i<=n; i++)
            {
                if(in[i]>out[i])sum+=in[i]-out[i],add(s,i,in[i]-out[i],0);
                else add(i,t,out[i]-in[i],0);
            }
            if(sum==maxflow())
            {
                cout<<"YES"<<endl;
                for(int i=0;i<2*m;i+=2)
                    cout<<e[i^1].c+e[i].low<<endl;
            }
            else cout<<"NO"<<endl;
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code
  • 相关阅读:
    移动应用专项测试
    MAC连接安卓手机通过adb指令安装apk
    Git GUI可视化操作教程
    nestjs中typeorm进行事物操作
    vue-element-admin 实现动态路由(从后台查询出菜单列表绑定侧边栏)
    el-form 表单校验
    vscode设置VUE eslint开发环境
    .netcore signalR 实时消息推送
    psexec局域网执行远程命令
    Asp.Net跨平台 Jexus 5.8.1 独立版
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7804159.html
Copyright © 2011-2022 走看看