标签:sha sum contain char 复习 下界 must lag perl
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
算是求有源汇上下界最大流的一道模板题···只不过建图有点麻烦····
先说有源汇上下界最大流最小流的基本求法(引用自农民伯伯-Coding):
对于流量有上下界的有源汇网络,原图中存在源点S和汇点T,为了求可行流,先将其转换为无源汇网络。
从T-->S引入一条边,其流量上下界为[0, INF],此时原图变为了无源汇网络,然后按照无源汇网络求解可行流的方法来求解。
要求最大流,先求可行流,通过“有源汇网络的可行流”的求解方法来判断有源汇网络存在可行流。
若存在可行流,记从S流出的流量sum1,然后将T-->S的边取消,再次从S到T求解网络的最大流,记从S流出的流量sum2. 那么该有源汇网络的最大流为 sum1 + sum2.
其中,sum1是在网络满足流量下界的条件下,从源点S流出的流量;求出sum1之后,网络中可能还有余量可以继续增广,那么再次求解从S到T的最大流,得到sum2,sum1 + sum2即为最终的最大流。
求解有源汇网络最小流分为以下几步:
(1)对SS到TT求一次最大流,即为f1.(在有源汇的情况下,先把整个网络趋向必须边尽量满足的情况);
(2)添加一条边T-->S,流量上限为INF,这条边即为P.(构造无源网络)
(3)对SS到TT再次求最大流,即为f2。(判断此时的网络中存在可行流,同时求出SS-->TT最大流)
如果所有必须边都满流,证明存在可行解,原图的最小流为“流经边P的流量”(原图已经构造成无源汇网络,对于S同样满足 入流和==出流和,只有新添加的边流向S,而S的出流就是原图的最小流)。
注: 最小流求法的正确性不知如何证明,待继续学习。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=1000; const int M=1000005; const int inf=0x3f3f3f3f; int tot=1,first[N],next[M],go[M],rest[M],lev[N],cur[N]; int tr[N],tc[N],n,m,low[N][N],up[N][N],T,src,des,ss,tt,sum1,sum2,k,ans,id[N][N],p; bool jud[N][N]; inline void comb(int a,int b,int c) { next[++tot]=first[a],first[a]=tot,go[tot]=b,rest[tot]=c; next[++tot]=first[b],first[b]=tot,go[tot]=a,rest[tot]=0; } inline void comb1(int a,int b,int c) { next[tot]=first[a],first[a]=tot,go[tot]=b,rest[tot]=c; next[++tot]=first[b],first[b]=tot,go[tot]=a,rest[tot]=0; } inline int R() { char c; int f=0; for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()); for(;c<=‘9‘&&c>=‘0‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f; } inline void pre() { memset(first,0,sizeof(first)); memset(low,0,sizeof(low)); memset(up,inf,sizeof(up)); memset(tr,0,sizeof(tr)); memset(tc,0,sizeof(tc)); tot=1,src=0,des=n+m+1,ss=n+m+2,tt=n+m+3,sum1=0,sum2=0,ans=0; } inline bool bfs() { for(int i=src;i<=tt;i++) cur[i]=first[i],lev[i]=-1; static int que[N],tail,u,v; que[tail=1]=ss; lev[ss]=0; for(int head=1;head<=tail;head++) { u=que[head]; for(int e=first[u];e;e=next[e]) { if(lev[v=go[e]]==-1&&rest[e]) { lev[v]=lev[u]+1; que[++tail]=v; if(v==tt) return true; } } } return false; } inline int dinic(int u,int flow) { if(u==tt) return flow; int res=0,delta,v; for(int &e=cur[u];e;e=next[e]) { if(lev[v=go[e]]>lev[u]&&rest[e]) { delta=dinic(v,min(flow-res,rest[e])); if(delta) { rest[e]-=delta; rest[e^1]+=delta; res+=delta; if(res==flow) break; } } } if(flow!=res) lev[u]=-1; return res; } inline void maxflow() { while(bfs()) ans+=dinic(ss,inf); } int main() { //freopen("a.in","r",stdin); T=R(); int a,b,c; char s[5]; while(T--) { scanf("\n"); n=R(),m=R(); pre(); for(int i=1;i<=n;i++) { a=R(); tc[src]+=a,tr[i]+=a; sum1+=a; } for(int i=1;i<=m;i++) { a=R(); tr[des]+=a,tc[n+i]+=a; sum2+=a; } if(sum1!=sum2) { cout<<"IMPOSSIBLE"<<endl; cout<<endl; continue; } k=R(); while(k--) { scanf("%d%d%s%d",&a,&b,s,&c); if(a==0&&b==0) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(s[0]==‘=‘) { low[i][j]=max(low[i][j],c); up[i][j]=min(up[i][j],c); } if(s[0]==‘<‘) up[i][j]=min(up[i][j],c-1); if(s[0]==‘>‘) low[i][j]=max(low[i][j],c+1); } } else if(a==0) for(int i=1;i<=n;i++) { if(s[0]==‘=‘) { low[i][b]=max(low[i][b],c); up[i][b]=min(up[i][b],c); } if(s[0]==‘<‘) up[i][b]=min(up[i][b],c-1); if(s[0]==‘>‘) low[i][b]=max(low[i][b],c+1); } else if(b==0) for(int i=1;i<=m;i++) { if(s[0]==‘=‘) { low[a][i]=max(low[a][i],c); up[a][i]=min(up[a][i],c); } if(s[0]==‘<‘) up[a][i]=min(up[a][i],c-1); if(s[0]==‘>‘) low[a][i]=max(low[a][i],c+1); } else { if(s[0]==‘=‘) { low[a][b]=max(low[a][b],c); up[a][b]=min(up[a][b],c); } if(s[0]==‘<‘) up[a][b]=min(up[a][b],c-1); if(s[0]==‘>‘) low[a][b]=max(low[a][b],c+1); } } bool flag=false; for(int i=1;i<=n;i++) { if(flag==true) break; for(int j=1;j<=m;j++) { if(low[i][j]>up[i][j]) { flag=true; break; } else { tr[n+j]+=low[i][j]; tc[i]+=low[i][j]; id[i][j]=++tot; comb1(i,n+j,up[i][j]-low[i][j]); } } } if(flag==true) { cout<<"IMPOSSIBLE"<<endl; cout<<endl; continue; } int cnt=0; p=++tot; comb1(des,src,inf); for(int i=src;i<=des;i++) { if(tr[i]>tc[i]) { comb(ss,i,tr[i]-tc[i]); cnt+=tr[i]-tc[i]; } if(tc[i]>tr[i]) comb(i,tt,tc[i]-tr[i]); } maxflow(); if(ans!=cnt) { cout<<"IMPOSSIBLE"<<endl; cout<<endl; continue; } rest[p]=rest[p^1]=0; maxflow(); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) cout<<rest[id[i][j]^1]+low[i][j]<<" "; cout<<endl; } cout<<endl; } return 0; }
标签:sha sum contain char 复习 下界 must lag perl
原文地址:http://www.cnblogs.com/AseanA/p/7482808.html