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

    题意:给一些约束条件,要求算能否有可行流,ps:刚开始输入的是每一列和,那么就建一条上下界相同的边,这样满流的时候就一定能保证流量相同了,还有0是该列(行)对另一行每个点都要满足约束条件

    解法:先按无源汇上下界可行流建边,然后添加一条从t到s的容量为inf的边,从超级源到超级汇跑一边最大流,看流量是不是等于新加边的流量和,注意这题有可能输入的数据会有锚段,那么我们需要特判一下是否有矛盾出现

    还要注意的一点是:我刚开始是用string+cin读入的字符,但是出现了问题,导致我代码下面的那组数据不能运行,改成scanf却能运行了,为什么单个字符就不能用string读入呢,还是说有其他的格式问题?

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #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=1000+10,maxn=160000+10,inf=0x3f3f3f3f;
    
    struct edge{
        int from,to,Next,c,low;
    }e[maxn<<2];
    int cnt,head[N];
    int in[N],out[N];
    int dis[N];
    int minn[N][N],maxx[N][N];
    void add(int u,int v,int c,int low)
    {
      //  cout<<u<<" "<<v<<" "<<c<<" "<<low<<endl;
        out[u]+=low;
        in[v]+=low;
        e[cnt].from=u;
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].low=low;
        e[cnt].Next=head[u];
        head[u]=cnt++;
        e[cnt].from=v;
        e[cnt].to=u;
        e[cnt].c=0;
        e[cnt].low=low;
        e[cnt].Next=head[v];
        head[v]=cnt++;
    }
    void init(int n,int m)
    {
        cnt=0;
        memset(head,-1,sizeof head);
        memset(in,0,sizeof in);
        memset(out,0,sizeof out);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                minn[i][j]=0,maxx[i][j]=inf;
    }
    bool bfs(int s,int t)
    {
        memset(dis,-1,sizeof dis);
        dis[s]=0;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            if(x==t)return 1;
            for(int i=head[x];~i;i=e[i].Next)
            {
                int te=e[i].to;
                if(dis[te]==-1&&e[i].c>0)
                {
                    dis[te]=dis[x]+1;
                    q.push(te);
                }
            }
        }
        return 0;
    }
    int dfs(int x,int mx,int t)
    {
        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),t)))
            {
                e[i].c-=f;
                e[i^1].c+=f;
                flow+=f;
            }
        }
        if(!flow)dis[x]=-2;
        return flow;
    }
    int maxflow(int s,int t)
    {
        int ans=0,f;
        while(bfs(s,t))
        {
            while((f=dfs(s,inf,t)))ans+=f;
        }
        return ans;
    }
    int main()
    {
       /* ios::sync_with_stdio(false);
        cin.tie(0);*/
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            init(n,m);
            int s=n+m+1,t=n+m+2,sum1=0,sum2=0;
            bool can=1;
            for(int i=1;i<=n;i++)
            {
                int a;
                scanf("%d",&a);
                sum1+=a;
                add(s,i,0,a);
                if(a<0)can=0;
            }
            for(int i=1;i<=m;i++)
            {
                int a;
                scanf("%d",&a);
                sum2+=a;
                add(i+n,t,0,a);
                if(a<0)can=0;
            }
            int res;
            scanf("%d",&res);
            while(res--)
            {
                int a,b,c;char str;
                scanf("%d %d %c %d",&a,&b,&str,&c);
                if(str=='<'&&c<0)can=0;
                if(str=='=')
                {
                    if(a==0&&b==0)
                    {
                        for(int i=1;i<=n;i++)
                            for(int j=1;j<=m;j++)
                            {
                                minn[i][j]=max(minn[i][j],c);
                                maxx[i][j]=min(maxx[i][j],c);
                            }
                    }
                    else if(a!=0&&b==0)
                    {
                        for(int j=1;j<=m;j++)
                        {
                            minn[a][j]=max(minn[a][j],c);
                            maxx[a][j]=min(maxx[a][j],c);
                        }
                    }
                    else if(a==0&&b!=0)
                    {
                        for(int i=1;i<=n;i++)
                        {
                            minn[i][b]=max(minn[i][b],c);
                            maxx[i][b]=min(maxx[i][b],c);
                        }
                    }
                    else if(a!=0&&b!=0)
                    {
                        minn[a][b]=max(minn[a][b],c);
                        maxx[a][b]=min(maxx[a][b],c);
                    }
                }
                else if(str=='>')
                {
                    if(a==0&&b==0)
                    {
                        for(int i=1;i<=n;i++)
                            for(int j=1;j<=m;j++)
                            {
                                minn[i][j]=max(minn[i][j],c+1);
                            }
                    }
                    else if(a!=0&&b==0)
                    {
                        for(int j=1;j<=m;j++)
                        {
                            minn[a][j]=max(minn[a][j],c+1);
                        }
                    }
                    else if(a==0&&b!=0)
                    {
                        for(int i=1;i<=n;i++)
                        {
                            minn[i][b]=max(minn[i][b],c+1);
                        }
                    }
                    else if(a!=0&&b!=0)
                    {
                        minn[a][b]=max(minn[a][b],c+1);
                    }
                }
                else
                {
                    if(a==0&&b==0)
                    {
                        for(int i=1;i<=n;i++)
                            for(int j=1;j<=m;j++)
                            {
                                maxx[i][j]=min(maxx[i][j],c-1);
                            }
                    }
                    else if(a!=0&&b==0)
                    {
                        for(int j=1;j<=m;j++)
                        {
                            maxx[a][j]=min(maxx[a][j],c-1);
                        }
                    }
                    else if(a==0&&b!=0)
                    {
                        for(int i=1;i<=n;i++)
                        {
                            maxx[i][b]=min(maxx[i][b],c-1);
                        }
                    }
                    else if(a!=0&&b!=0)
                    {
                        maxx[a][b]=min(maxx[a][b],c-1);
                    }
                }
            }
            int be=cnt;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                //    cout<<maxx[i][j]<<" "<<minn[i][j]<<endl;
                    if(maxx[i][j]<minn[i][j])can=0;
                    add(i,j+n,maxx[i][j]-minn[i][j],minn[i][j]);
                }
            }
            int en=cnt-1;
            add(t,s,inf,0);
            int ss=n+m+3,tt=n+m+4,sum3=0;
            for(int i=1;i<=n+m+2;i++)
            {
                if(in[i]>out[i])add(ss,i,in[i]-out[i],0),sum3+=in[i]-out[i];
                else add(i,tt,out[i]-in[i],0);
            }
            if(sum1!=sum2||!can||sum3!=maxflow(ss,tt))puts("IMPOSSIBLE");
            else
            {
                can=1;
                for(int i=be;i<=en;i+=2)
                {
                    if(e[i^1].c+e[i].low<0)
                    {
                        can=0;
                        break;
                    }
                }
                if(can==0)puts("IMPOSSIBLE");
                else
                {
                    int co=0;
                    for(int i=be;i<=en;i+=2)
                    {
                        printf("%d",e[i^1].c+e[i].low);
                        co++;
                        if(co!=m)printf("%c",' ');
                        else puts(""),co=0;
                    }
                }
            }
            puts("");
        }
        return 0;
    }
    /********************
    179 20
    10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000
    89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500 89500
    5
    130 0 > 307
    0 0 < 366
    0 0 > 329
    0 0 < 341
    0 0 < 324
    ********************/
    View Code
  • 相关阅读:
    在VMWare虚拟机下的ubuntu中Samba服务的安装
    Shell表达式,如${file##*/}
    如何从官网下载QT
    SATA命令之security
    Clip
    JS判断是否在微信浏览器打开
    微信小程序请求数据报错: 如若已在管理后台更新域名配置,请刷新项目配置后重新编译项目,操作路径:“详情-域名信息”
    typeof()和instanceof的用法区别
    javascrip 对数组的操作方法
    微信小程序 修改数据,并动态渲染页面;修改数组;
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7808468.html
Copyright © 2011-2022 走看看