Time Limit: 3000MS | Memory Limit: 65536K | |||
Total Submissions: 3250 | Accepted: 1227 | Special Judge |
Description
Input
Output
Sample Input
2 2 3 8 10 5 6 7 4 0 2 > 2 2 1 = 3 2 3 > 2 2 3 < 5 2 2 4 5 6 7 1 1 1 > 10
Sample Output
2 3 3 3 3 4 IMPOSSIBLE
Source
分析:这题构图比较简单,关键是被坑了,<的时候,要把花费-1,>的时候要+1,=不变。。。。,因此wa了一次
构图:把每一行看成一个点,每一列也看成一个点,增设源和汇,源到该列对应的边的上下界为该列的和,行类似,根据第i行第j列的情况求i行对应的点到j列对应的点的边的上下界,然后求可行流即可~~~
代码:
#include<cstdio> using namespace std; const int mm=22222; const int mn=1111; const int oo=1000000000; int node,src,dest,edge,n,m; int ver[mm],flow[mm],next[mm],in[mm]; int head[mn],work[mn],dis[mn],q[mn]; int low[222][22],high[222][22]; inline int min(int a,int b) { return a<b?a:b; } inline int max(int a,int b) { return a>b?a:b; } inline void prepare(int _node,int _src,int _dest) { node=_node,src=_src,dest=_dest; for(int i=0;i<node;++i)head[i]=-1,in[i]=0; edge=0; } inline void addedge(int u,int v,int c) { ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++; ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++; } bool Dinic_bfs() { int i,u,v,l,r=0; for(i=0;i<node;++i)dis[i]=-1; dis[q[r++]=src]=0; for(l=0;l<r;++l) for(i=head[u=q[l]];i>=0;i=next[i]) if(flow[i]&&dis[v=ver[i]]<0) { dis[q[r++]=v]=dis[u]+1; if(v==dest)return 1; } return 0; } int Dinic_dfs(int u,int exp) { if(u==dest)return exp; for(int &i=work[u],v,tmp;i>=0;i=next[i]) if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0) { flow[i]-=tmp; flow[i^1]+=tmp; return tmp; } return 0; } void Dinic_flow() { int i; while(Dinic_bfs()) { for(i=0;i<node;++i)work[i]=head[i]; while(Dinic_dfs(src,oo)); } } bool ok() { for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(low[i][j]>high[i][j])return 0; else { in[i]-=low[i][j],in[n+j]+=low[i][j]; addedge(i,j+n,high[i][j]-low[i][j]); } return 1; } void limit_min_flow() { int i,j,src0,dest0; src0=src,dest0=dest; src=node,dest=node+1; head[src]=head[dest]=-1; for(i=0;i<node;++i) { if(in[i]>0)addedge(src,i,in[i]); if(in[i]<0)addedge(i,dest,-in[i]); } node+=2; addedge(dest0,src0,oo); Dinic_flow(); for(i=head[src];i>=0;i=next[i]) if(flow[i]) { printf("IMPOSSIBLE\n\n"); return; } for(i=head[dest0];i>=0;i=next[i]) if(ver[i]==src0)break; if(i<0) { printf("IMPOSSIBLE\n\n"); return; } for(i=1;i<=n;printf("%d\n",flow[i*m*2-1]+low[i][j]),++i) for(j=1;j<m;++j)printf("%d ",flow[((i-1)*m+j)*2-1]+low[i][j]); printf("\n"); } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int i,j,c,t,s; char k; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); prepare(n+m+2,0,n+m+1); for(i=1;i<=n;++i)scanf("%d",&c),in[src]-=c,in[i]+=c; for(i=1;i<=m;++i)scanf("%d",&c),in[i+n]-=c,in[dest]+=c; for(i=1;i<=n;++i) for(j=1;j<=m;++j)low[i][j]=0,high[i][j]=oo; scanf("%d",&s); while(s--) { scanf("%d%d",&i,&j); while((k=getchar())==' '); scanf("%d",&c); if(k=='<') { --c; if(i&&j)high[i][j]=min(high[i][j],c); else if(i)for(j=1;j<=m;++j)high[i][j]=min(high[i][j],c); else if(j)for(i=1;i<=n;++i)high[i][j]=min(high[i][j],c); else for(i=1;i<=n;++i) for(j=1;j<=m;++j)high[i][j]=min(high[i][j],c); } else if(k=='>') { ++c; if(i&&j)low[i][j]=max(low[i][j],c); else if(i)for(j=1;j<=m;++j)low[i][j]=max(low[i][j],c); else if(j)for(i=1;i<=n;++i)low[i][j]=max(low[i][j],c); else for(i=1;i<=n;++i) for(j=1;j<=m;++j)low[i][j]=max(low[i][j],c); } else { if(i&&j)low[i][j]=max(low[i][j],c),high[i][j]=min(high[i][j],c); else if(i)for(j=1;j<=m;++j)low[i][j]=max(low[i][j],c),high[i][j]=min(high[i][j],c); else if(j)for(i=1;i<=n;++i)low[i][j]=max(low[i][j],c),high[i][j]=min(high[i][j],c); else for(i=1;i<=n;++i) for(j=1;j<=m;++j)low[i][j]=max(low[i][j],c),high[i][j]=min(high[i][j],c); } } if(ok())limit_min_flow(); else printf("IMPOSSIBLE\n\n"); } return 0; }