poj 2396
有上下界的网络流,非主流做法。
#include<iostream> #include<fstream> #include<queue> using namespace std; int n; int c[250][250],pre[250],f[250][250]; int d[250],flow; int v[250]; typedef struct e{ int data; e *next; }e; e edge[250]; int build(){ int i,j,k; queue<int> q; q.push(1); memset(d,0,sizeof(d)); d[1]=1; while(!q.empty()) { i=q.front(); q.pop(); e *p=edge[i].next; while(p) { j=p->data; if(d[j]==0&&c[i][j]>f[i][j]) { d[j]=d[i]+1; if(j==n) return 1; q.push(j); } p=p->next; } } return 0; } int find(int m,int minw){ int i,j,k; if(m==n) return minw; v[m]=1; e *p=edge[m].next; while(p) { i=p->data; if(c[m][i]>f[m][i]&&d[i]==d[m]+1&&v[i]==0) { j=find(i,min(minw,c[m][i]-f[m][i])); if(j) { f[m][i]+=j; f[i][m]=-1*f[m][i]; return j; } } p=p->next; } return 0; } int solve(){ int i,j,k; flow=0; memset(f,0,sizeof(f)); while(build()) while(1){ memset(v,0,sizeof(v)); i=10000000; k=find(1,i); flow+=k; if(k==0) break; } return flow; } int a[210][21]; int b[210][21]; int h1[210]; int h2[21]; void read(){ // ifstream cin("in.txt"); int i,j,k,s,t,value; int K,m; cin>>K; while(K--) { cin>>n>>m; int sum=0,sum2=0; memset(edge,0,sizeof(edge)); memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); memset(b,-1,sizeof(b)); memset(h1,0,sizeof(h1)); memset(h2,0,sizeof(h2)); for(i=1;i<=n;i++) { cin>>c[1][i+1]; sum+=c[1][i+1]; e *p=new e; p->data=i+1; p->next=edge[1].next; edge[1].next=p; e* q=new e; q->data=1; q->next=edge[i+1].next; edge[i+1].next=q; } for(i=1;i<=m;i++) { cin>>c[1+n+i][n+m+2]; sum2+=c[1+n+i][n+m+2]; e *p=new e; p->data=n+m+2; p->next=edge[1+n+i].next; edge[1+n+i].next=p; e* q=new e; q->data=1+n+i; q->next=edge[n+m+2].next; edge[n+m+2].next=q; } if(sum!=sum2) { cout<<"IMPOSSIBLE"<<endl<<endl; continue; } cin>>k; char w; for(i=1;i<=k;i++) { cin>>s>>t>>w>>value; if(w=='=') { if(s==0&&t==0) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { a[i][j]=value; b[i][j]=value; } } else if(s==0) { for(int i=1;i<=n;i++) { a[i][t]=value; b[i][t]=value; } } else if(t==0) { for(int i=1;i<=m;i++) { a[s][i]=value; b[s][i]=value; } } else { a[s][t]=value; b[s][t]=value; } } if(w=='>') { value++; if(s==0&&t==0) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { a[i][j]=max(a[i][j],value); } } else if(s==0) { for(int i=1;i<=n;i++) { a[i][t]=max(a[i][t],value); } } else if(t==0) { for(int i=1;i<=m;i++) { a[s][i]=max(a[s][i],value); } } else { a[s][t]=max(a[s][t],value); } } if(w=='<') { value--; if(s==0&&t==0) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(b[i][j]!=-1) b[i][j]=min(b[i][j],value); else b[i][j]=value; } } else if(s==0) { for(int i=1;i<=n;i++) { if(b[i][t]!=-1) b[i][t]=min(b[i][t],value); else b[i][t]=value; } } else if(t==0) { for(int i=1;i<=m;i++) { if(b[s][i]!=-1) b[s][i]=min(value,b[s][i]); else b[s][i]=value; } } else { if(b[s][t]==-1) b[s][t]=value; else b[s][t]=min(b[s][t],value); } } } for(i=1;i<=n;i++) for(j=1;j<=m;j++) { if(b[i][j]==-1) b[i][j]=1000000; h1[i]+=a[i][j]; h2[j]+=a[i][j]; c[i+1][j+n+1]=b[i][j]-a[i][j]; e *p=new e; p->data=j+n+1; p->next=edge[i+1].next; edge[i+1].next=p; e*q=new e; q->data=i+1; q->next=edge[j+n+1].next; edge[j+n+1].next=q; } for(i=1;i<=m;i++) { c[1][i+n+1]=h2[i]; e *p=new e; p->data=i+n+1; p->next=edge[1].next; edge[1].next=p; e *q=new e; q->data=1; q->next=edge[i+n+1].next; edge[i+n+1].next=q; } for(i=1;i<=n;i++) { c[i+1][m+n+2]=h1[i]; e *p=new e; p->data=n+m+2; p->next=edge[1+i].next; edge[1+i].next=p; e *q=new e; q->data=i+1; q->next=edge[m+n+2].next; edge[m+n+2].next=q; } n=n+m+2; solve(); n-=m+2; int row[210]; int colon[21]; memset(row,0,sizeof(row)); memset(colon,0,sizeof(colon)); int sum1=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { row[i]+=f[i+1][j+n+1]+a[i][j]; colon[j]+=f[i+1][j+n+1]+a[i][j]; } } for(i=1;i<=n;i++) if(c[1][i+1]!=row[i]) { sum1=1; break; } if(sum1==0) for(i=1;i<=m;i++) if(c[1+n+i][n+m+2]!=colon[i]) { sum1=1; break; } if(sum1==0) { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) cout<<f[i+1][j+n+1]+a[i][j]<<' '; cout<<endl; } cout<<endl; } else cout<<"IMPOSSIBLE"<<endl<<endl; } } int main(){ read(); return 0; }