ZOJ 1994Budget 有源汇上下界网络流 可行流

来源:互联网 发布:java ip查地区 编辑:程序博客网 时间:2024/06/05 11:01

ZOJ 1994 Budget 有源汇上下界网络流 可行流

题意:有一个n行m列的矩阵,每个点上都有一个非负整数,现在给出一些约束条件,约束条件的格式 x y op v ,op可能为>,<,=,对于每一个约束,如果x!=0&&y!=0(x,y) op v ,比如2 4 > 2 就是说(2,4)这个点的值要大于2。如果x0,则表示为y列的值都共享这个约束,如果y0,则代表x行的值都共享这个约束,如果xy都为0,则代表矩阵中所有数都共享这个约束。输出满足这些约束的任意可行方案,并输出矩阵中的值

若op为>则代表这个约束更新下界
若op为<则代表这个约束更新上界
若op为=则代表这个约束更新上下界

这题我写了两份代码。。。
代码1:

//author: CHC//First Edit Time:  2015-09-07 10:56#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=1e+4;const int MAXM=1e+6;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();struct Edge {    int to,ci,next;    Edge(){}    Edge(int _to,int _ci,int _next):to(_to),ci(_ci),next(_next){}}e[MAXM];int head[MAXN],tot;int dis[MAXN],sta[MAXN],top,cur[MAXN];void init(){    memset(head,-1,sizeof(head));    tot=0;}void AddEdge(int u,int v,int ci0,int ci1=0){    e[tot]=Edge(v,ci0,head[u]);    head[u]=tot++;    e[tot]=Edge(u,ci1,head[v]);    head[v]=tot++;}inline bool bfs(int st,int et){    memset(dis,0,sizeof(dis));    dis[st]=1;    queue <int> q;    q.push(st);    while(!q.empty()){        int now=q.front();        q.pop();        for(int i=head[now];~i;i=e[i].next){            if(e[i].ci&&!dis[e[i].to]){                dis[e[i].to]=dis[now]+1;                q.push(e[i].to);            }        }    }    return dis[et]!=0;}LL Dinic(int st,int et){    LL ans=0;    while(bfs(st,et)){        top=0;        memcpy(cur,head,sizeof(cur));        int u=st,i;        while(1){            if(u==et){                int pos,minn=INF;                for(i=0;i<top;i++){                    if(minn>e[sta[i]].ci){                        minn=e[sta[i]].ci;                        pos=i;                    }                }                for(i=0;i<top;i++){                    e[sta[i]].ci-=minn;                    e[sta[i]^1].ci+=minn;                }                top=pos;                u=e[sta[top]^1].to;                ans+=minn;            }            for(i=cur[u];~i;cur[u]=i=e[i].next)                if(e[i].ci&&dis[u]+1==dis[e[i].to])break;            if(cur[u]!=-1){                sta[top++]=cur[u];                u=e[cur[u]].to;            }            else {                if(top==0)break;                dis[u]=0;                u=e[sta[--top]^1].to;            }        }    }    return ans;}int all[3];int row[210][3],col[22][3];int ctag[210][22][3];int rncnt[210],cncnt[22];int n,m;int du[MAXN];int num[210][22],cha[210][22];int main(){    int t;    scanf("%d",&t);    int tflag=0;    while(t--){        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++){            scanf("%d",&rncnt[i]);        }        for(int i=1;i<=m;i++){            scanf("%d",&cncnt[i]);        }        int q;        scanf("%d",&q);        int x,y,v;        char ch;        memset(all,-1,sizeof(all));        memset(row,-1,sizeof(row));        memset(col,-1,sizeof(col));        memset(ctag,-1,sizeof(ctag));        int flag=0;        for(int i=0;i<q;i++){            scanf("%d%d %c%d",&x,&y,&ch,&v);            if(ch=='='&&v<0)flag=1;            if(ch=='>'&&v<0)v=0;            if(ch=='<'&&v<1)flag=1;            //if(v<0)flag=1;            //if(ch=='<'&&v==0)flag=1;            if(x==0&&y==0){                if(ch=='<'){                    if(all[0]==-1)all[0]=v;                    else all[0]=min(all[0],v);                }                else if(ch=='='){                    if(all[1]==-1)all[1]=v;                    else if(all[1]!=v)flag=1;                }                else {                    if(all[2]==-1)all[2]=v;                    else all[2]=max(all[2],v);                }            }            else if(x==0){                if(ch=='<'){                    if(col[y][0]==-1)col[y][0]=v;                    else col[y][0]=min(col[y][0],v);                }                else if(ch=='='){                    if(col[y][1]==-1)col[y][1]=v;                    else if(col[y][1]!=v)flag=1;                }                else {                    if(col[y][2]==-1)col[y][2]=v;                    else col[y][2]=max(col[y][2],v);                }            }            else if(y==0){                if(ch=='<'){                    if(row[x][0]==-1)row[x][0]=v;                    else row[x][0]=min(row[x][0],v);                }                else if(ch=='='){                    if(row[x][1]==-1)row[x][1]=v;                    else if(row[x][1]!=v)flag=1;                }                else {                    if(row[x][2]==-1)row[x][2]=v;                    else row[x][2]=max(row[x][2],v);                }            }            else {                if(ch=='<'){                    if(ctag[x][y][0]==-1)ctag[x][y][0]=v;                    else ctag[x][y][0]=min(ctag[x][y][0],v);                }                else if(ch=='='){                    if(ctag[x][y][1]==-1)ctag[x][y][1]=v;                    else if(ctag[x][y][1]!=v)flag=1;                }                else {                    if(ctag[x][y][2]==-1)ctag[x][y][2]=v;                    else ctag[x][y][2]=max(ctag[x][y][2],v);                }            }        }        if(tflag)puts("");        tflag=1;        if(flag){            puts("IMPOSSIBLE");            continue;        }        for(int i=1;i<=n;i++){            if(row[i][0]!=-1){                for(int j=1;j<=m;j++){                    if(ctag[i][j][0]==-1)ctag[i][j][0]=row[i][0];                    else ctag[i][j][0]=min(ctag[i][j][0],row[i][0]);                }            }            if(row[i][1]!=-1){                for(int j=1;j<=m;j++){                    if(ctag[i][j][1]==-1)ctag[i][j][1]=row[i][1];                    else if(ctag[i][j][1]!=row[i][1])flag=1;                }            }            if(row[i][2]!=-1){                for(int j=1;j<=m;j++){                    if(ctag[i][j][2]==-1)ctag[i][j][2]=row[i][2];                    else ctag[i][j][2]=max(ctag[i][j][2],row[i][2]);                }            }        }        //printf("flag:%d\n",flag);        for(int i=1;i<=m;i++){            if(col[i][0]!=-1){                for(int j=1;j<=n;j++){                    if(ctag[j][i][0]==-1)ctag[j][i][0]=col[i][0];                    else ctag[j][i][0]=min(ctag[j][i][0],col[i][0]);                }            }            if(col[i][1]!=-1){                for(int j=1;j<=n;j++){                    if(ctag[j][i][1]==-1)ctag[j][i][1]=col[i][1];                    else if(ctag[j][i][1]!=col[i][1])flag=1;                }            }            if(col[i][2]!=-1){                for(int j=1;j<=n;j++){                    if(ctag[j][i][2]==-1)ctag[j][i][2]=col[i][2];                    else ctag[j][i][2]=max(ctag[j][i][2],col[i][2]);                }            }        }        //printf("flag:%d\n",flag);        if(all[0]!=-1){            for(int i=1;i<=n;i++)                for(int j=1;j<=m;j++)                    if(ctag[i][j][0]==-1)ctag[i][j][0]=all[0];                    else ctag[i][j][0]=min(ctag[i][j][0],all[0]);        }        if(all[1]!=-1){            for(int i=1;i<=n;i++)                for(int j=1;j<=m;j++)                    if(ctag[i][j][1]==-1)ctag[i][j][1]=all[1];                    else if(ctag[i][j][1]!=all[1])flag=1;        }        if(all[2]!=-1){            for(int i=1;i<=n;i++)                for(int j=1;j<=m;j++)                    if(ctag[i][j][2]==-1)ctag[i][j][2]=all[2];                    else ctag[i][j][2]=max(ctag[i][j][2],all[2]);        }        //printf("flag:%d\n",flag);        if(flag){            puts("IMPOSSIBLE");            continue;        }        memset(du,0,sizeof(du));        memset(cha,0,sizeof(cha));        init();        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                if(ctag[i][j][0]!=-1&&ctag[i][j][2]!=-1){                    if(ctag[i][j][0]-1>=ctag[i][j][2]+1);                    else flag=1;                    //if(ctag[i][j][0]-1<=ctag[i][j][2])flag=1;                }                if(ctag[i][j][1]!=-1&&ctag[i][j][0]!=-1){                    if(ctag[i][j][1]<ctag[i][j][0]);                    else flag=1;                    //if(ctag[i][j][1]>=ctag[i][j][0])flag=1;                }                if(ctag[i][j][1]!=-1&&ctag[i][j][2]!=-1){                    if(ctag[i][j][1]>ctag[i][j][2]);                    else flag=1;                    //if(ctag[i][j][1]<=ctag[i][j][2])flag=1;                }                if(ctag[i][j][0]!=-1&&ctag[i][j][1]!=-1&&ctag[i][j][2]!=-1){                    if(ctag[i][j][1]<ctag[i][j][0]&&ctag[i][j][1]>ctag[i][j][2]);                    else flag=1;                }                if(ctag[i][j][1]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,0);                    cha[i][j]=ctag[i][j][1];                    du[i]-=ctag[i][j][1];                    du[j+n]+=ctag[i][j][1];                }                else if(ctag[i][j][0]!=-1&&ctag[i][j][2]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,ctag[i][j][0]-1-(ctag[i][j][2]+1));                    cha[i][j]=ctag[i][j][2]+1;                    du[i]-=ctag[i][j][2]+1;                    du[j+n]+=ctag[i][j][2]+1;                }                else if(ctag[i][j][0]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,ctag[i][j][0]-1);                }                else if(ctag[i][j][2]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,INF-(ctag[i][j][2]+1));                    cha[i][j]=ctag[i][j][2]+1;                    du[i]-=ctag[i][j][2]+1;                    du[j+n]+=ctag[i][j][2]+1;                }                else {                    num[i][j]=tot;                    AddEdge(i,j+n,INF);                }            }        }        //printf("flag:%d\n",flag);        if(flag){            puts("IMPOSSIBLE");            continue;        }        int st=n+m+1,et=n+m+2;        for(int i=1;i<=n;i++){            //AddEdge(st,i,rncnt[i]);            du[st]-=rncnt[i];            du[i]+=rncnt[i];        }        for(int i=1;i<=m;i++){            //AddEdge(n+i,et,cncnt[i]);            du[n+i]-=cncnt[i];            du[et]+=cncnt[i];        }        int sst=n+m+3,eet=n+m+4;        LL ctot=0;        for(int i=1;i<=et;i++){            if(du[i]>0)AddEdge(sst,i,du[i]),ctot+=du[i];            else AddEdge(i,eet,-du[i]);        }        AddEdge(et,st,INF);        //if(du[st]>0)AddEdge(sst,st,du[st]),ctot+=du[st];        //else AddEdge(st,eet,-du[st]);        //if(du[et]>0)AddEdge(sst,et,du[et]),ctot+=du[et];        //else AddEdge(et,eet,-du[et]);        LL ans=Dinic(sst,eet);        if(ans!=ctot)puts("IMPOSSIBLE");        else {            //ans=Dinic(st,et);            //printf("%I64d\n",ans);            for(int i=1;i<=n;i++){                for(int j=1;j<m;j++){                    printf("%d ",e[num[i][j]^1].ci+cha[i][j]);                }                printf("%d\n",e[num[i][m]^1].ci+cha[i][m]);            }            //puts("");        }    }    return 0;}

代码2:

//author: CHC//First Edit Time:  2015-09-08 00:22#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=1e+4;const int MAXM=1e+5;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();struct Edge {    int to,ci,next;    Edge(){}    Edge(int _to,int _ci,int _next):to(_to),ci(_ci),next(_next){}}e[MAXM];int head[MAXN],tot;int dis[MAXN],sta[MAXN],top,cur[MAXN];void init(){    memset(head,-1,sizeof(head));    tot=0;}void AddEdge(int u,int v,int ci0,int ci1=0){    e[tot]=Edge(v,ci0,head[u]);    head[u]=tot++;    e[tot]=Edge(u,ci1,head[v]);    head[v]=tot++;}inline bool bfs(int st,int et){    memset(dis,0,sizeof(dis));    dis[st]=1;    queue <int> q;    q.push(st);    while(!q.empty()){        int now=q.front();        q.pop();        for(int i=head[now];~i;i=e[i].next){            if(e[i].ci&&!dis[e[i].to]){                dis[e[i].to]=dis[now]+1;                q.push(e[i].to);            }        }    }    return dis[et]!=0;}LL Dinic(int st,int et){    LL ans=0;    while(bfs(st,et)){        top=0;        memcpy(cur,head,sizeof(cur));        int u=st,i;        while(1){            if(u==et){                int pos,minn=INF;                for(i=0;i<top;i++){                    if(minn>e[sta[i]].ci){                        minn=e[sta[i]].ci;                        pos=i;                    }                }                for(i=0;i<top;i++){                    e[sta[i]].ci-=minn;                    e[sta[i]^1].ci+=minn;                }                top=pos;                u=e[sta[top]^1].to;                ans+=minn;            }            for(i=cur[u];~i;cur[u]=i=e[i].next)                if(e[i].ci&&dis[u]+1==dis[e[i].to])break;            if(cur[u]!=-1){                sta[top++]=cur[u];                u=e[cur[u]].to;            }            else {                if(top==0)break;                dis[u]=0;                u=e[sta[--top]^1].to;            }        }    }    return ans;}int du[500],ctag[300][300][3];int num[300][300],base[300][300];int main(){    int t,n,m;    scanf("%d",&t);    int tflag=0;    while(t--){        scanf("%d%d",&n,&m);        while(n>200||m>20||n<=0||m<=0);        int st=0,et=n+m+1;        int s1=0;        memset(ctag,-1,sizeof(ctag));        memset(du,0,sizeof(du));        init();        for(int i=1,x;i<=n;i++){            scanf("%d",&x);            s1+=x;            du[st]-=x;            du[i]+=x;        }        for(int i=1,x;i<=m;i++){            scanf("%d",&x);            s1-=x;            du[i+n]-=x;            du[et]+=x;        }        int q;        int x[2],y[2],v;        char ch[10];        scanf("%d",&q);        int flag=0;        while(q--){            scanf("%d%d %s %d",&x[0],&y[0],ch,&v);            if(ch[0]=='='&&v<0){                flag=1;                while(1);            }            if(ch[0]=='<'&&v<=0){                flag=1;                while(1);            }            if(ch[0]=='>'&&v+1<0){                v=0;                //while(1);            }            x[1]=x[0];y[1]=y[0];            if(x[0]==0)x[0]=1,x[1]=n;            if(y[0]==0)y[0]=1,y[1]=m;            //printf("%d %d %d %d\n",x[0],x[1],y[0],y[1]);            for(int i=x[0];i<=x[1];i++)                for(int j=y[0];j<=y[1];j++){                    if(ch[0]=='<'){                        if(ctag[i][j][0]==-1)ctag[i][j][0]=v-1;                        else ctag[i][j][0]=min(ctag[i][j][0],v-1);                    }                    else if(ch[0]=='='){                        if(ctag[i][j][1]==-1)ctag[i][j][1]=v;                        else if(ctag[i][j][1]!=v)flag=1;                    }                    else if(ch[0]=='>'){                        if(ctag[i][j][2]==-1)ctag[i][j][2]=v+1;                        else ctag[i][j][2]=max(ctag[i][j][2],v+1);                    }                }        }        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++){                if(ctag[i][j][0]!=-1&&ctag[i][j][2]!=-1){                    if(ctag[i][j][0]>=ctag[i][j][2]);                    else flag=1;                }                if(ctag[i][j][0]!=-1&&ctag[i][j][1]!=-1){                    if(ctag[i][j][1]<=ctag[i][j][0]);                    else flag=1;                }                if(ctag[i][j][1]!=-1&&ctag[i][j][2]!=-1){                    if(ctag[i][j][1]>=ctag[i][j][2]);                    else flag=1;                }            }        if(tflag)puts("");        tflag=1;        if(flag){            printf("IMPOSSIBLE\n");            //while(1);            //puts("");            continue;        }        int sst=et+1,eet=et+2;        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++){                if(ctag[i][j][1]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,0);                    base[i][j]=ctag[i][j][1];                    du[i]-=ctag[i][j][1];                    du[j+n]+=ctag[i][j][1];                }                else if(ctag[i][j][0]!=-1&&ctag[i][j][2]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,ctag[i][j][0]-ctag[i][j][2]);                    du[i]-=ctag[i][j][2];                    du[j+n]+=ctag[i][j][2];                    base[i][j]=ctag[i][j][2];                }                else if(ctag[i][j][0]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,ctag[i][j][0]);                    base[i][j]=0;                }                else if(ctag[i][j][2]!=-1){                    num[i][j]=tot;                    AddEdge(i,j+n,INF-ctag[i][j][2]);                    du[i]-=ctag[i][j][2];                    du[j+n]+=ctag[i][j][2];                    base[i][j]=ctag[i][j][2];                }                else {                    num[i][j]=tot;                    AddEdge(i,j+n,INF);                    base[i][j]=0;                }            }        LL ctot=0;        for(int i=0;i<=et;i++){            if(du[i]>0)AddEdge(sst,i,du[i]),ctot+=du[i];            else AddEdge(i,eet,-du[i]);        }        AddEdge(et,st,INF);        LL ans=Dinic(sst,eet);        if(ans!=ctot||s1!=0){            printf("IMPOSSIBLE\n");            //while(1);        }        else {            for(int i=1;i<=n;i++){                for(int j=1;j<m;j++)printf("%d ",e[num[i][j]^1].ci+base[i][j]);                printf("%d\n",e[num[i][m]^1].ci+base[i][m]);            }            //puts("");        }    }    return 0;}
0 0
原创粉丝点击