标签:foo special ued meeting color site mat exist ber
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
题意
给你N行和和M行列,再给你一堆约束条件,问你是否存在N*M的矩阵满足条件
题解
有源汇上下界网络流经典题
这类题通常是从建完图发现源点s流出到汇点t流量,然后有些边有上下界条件
做法是把汇点连边流向源点流量为INF,让它变成一个循环流
然后就变成了无源汇上下界网络流问题,新建超级源点S,超级汇点T
令Mi=点总流入-点总流出
如果Mi>0,说明该点需要流出Mi流量,则建边S->i流量Mi
如果Mi<0,说明该点需要流入Mi流量,则建边i->T流量Mi
跑一边S->T的最大流求出一个可行流,可以得到每条边的流量,再加上下界就是答案
比如样例
2 2
2 2
2 2
2
0 0 > 1
0 0 < 10
建完图发现是N*M的矩阵
0 3 0
3 3 3
跑完最大流得到可行流
2 0 3
0 0 1
相加后得到答案
代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 const int maxn=1e5+5; 7 const int maxm=2e5+5; 8 const int INF=0x3f3f3f3f; 9 10 int TO[maxm],CAP[maxm],NEXT[maxm],tote; 11 int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[400000]; 12 int n,m,S,T; 13 14 void add(int u,int v,int cap) 15 { 16 //printf("i=%d u=%d v=%d cap=%d\n",tote,u,v,cap); 17 TO[tote]=v; 18 CAP[tote]=cap; 19 NEXT[tote]=FIR[u]; 20 FIR[u]=tote++; 21 22 TO[tote]=u; 23 CAP[tote]=0; 24 NEXT[tote]=FIR[v]; 25 FIR[v]=tote++; 26 } 27 void bfs() 28 { 29 memset(gap,0,sizeof gap); 30 memset(d,0,sizeof d); 31 ++gap[d[T]=1]; 32 for(int i=1;i<=n;++i)cur[i]=FIR[i]; 33 int head=1,tail=1; 34 q[1]=T; 35 while(head<=tail) 36 { 37 int u=q[head++]; 38 for(int v=FIR[u];v!=-1;v=NEXT[v]) 39 if(!d[TO[v]]) 40 ++gap[d[TO[v]]=d[u]+1],q[++tail]=TO[v]; 41 } 42 } 43 int dfs(int u,int fl) 44 { 45 if(u==T)return fl; 46 int flow=0; 47 for(int &v=cur[u];v!=-1;v=NEXT[v]) 48 if(CAP[v]&&d[u]==d[TO[v]]+1) 49 { 50 int Min=dfs(TO[v],min(fl,CAP[v])); 51 flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^1]+=Min; 52 if(!fl)return flow; 53 } 54 if(!(--gap[d[u]]))d[S]=n+1; 55 ++gap[++d[u]],cur[u]=FIR[u]; 56 return flow; 57 } 58 int ISAP() 59 { 60 bfs(); 61 int ret=0; 62 while(d[S]<=n)ret+=dfs(S,INF); 63 return ret; 64 } 65 66 int ca,N,M,Q,x,y,z,l[205][25],r[205][25]; 67 char op[2]; 68 69 void init() 70 { 71 tote=0; 72 memset(FIR,-1,sizeof FIR); 73 memset(l,0,sizeof l); 74 memset(r,INF,sizeof r); 75 } 76 void update(int x,int y) 77 { 78 if(op[0]==‘>‘)l[x][y]=max(l[x][y],z+1); 79 else if(op[0]==‘=‘)l[x][y]=max(l[x][y],z),r[x][y]=min(r[x][y],z); 80 else if(op[0]==‘<‘)r[x][y]=min(r[x][y],z-1); 81 } 82 bool build() 83 { 84 init(); 85 scanf("%d%d",&N,&M); 86 int s=N+M+1,t=N+M+2; 87 int in[250]={0},sum=0,sum1=0; 88 add(t,s,INF); 89 S=N+M+3,T=N+M+4,n=T; 90 for(int i=1;i<=N;i++) 91 scanf("%d",&x),add(s,T,x),in[i]+=x,in[s]-=x,sum+=x; 92 for(int i=1;i<=M;i++) 93 scanf("%d",&x),add(S,t,x),in[i+N]-=x,in[t]+=x,sum1+=x; 94 scanf("%d",&Q); 95 for(int i=1;i<=Q;i++) 96 { 97 scanf("%d%d%s%d",&x,&y,op,&z); 98 if(!x&&!y) 99 for(int i=1;i<=N;i++) 100 for(int j=1;j<=M;j++) 101 update(i,j); 102 else if(!x) 103 for(int i=1;i<=N;i++) 104 update(i,y); 105 else if(!y) 106 for(int i=1;i<=M;i++) 107 update(x,i); 108 else 109 update(x,y); 110 } 111 if(sum!=sum1)return 0; 112 for(int i=1;i<=N;i++) 113 for(int j=1;j<=M;j++) 114 { 115 if(l[i][j]>r[i][j])return 0; 116 add(i,j+N,r[i][j]-l[i][j]); 117 in[i]-=l[i][j]; 118 in[j+N]+=l[i][j]; 119 } 120 for(int i=1;i<=N+M+2;i++) 121 if(in[i]>0) 122 { 123 add(S,i,in[i]); 124 sum+=in[i]; 125 } 126 else 127 add(i,T,-in[i]); 128 return sum==ISAP(); 129 } 130 int main() 131 { 132 int _; 133 scanf("%d",&_); 134 for(ca=0;ca<_;ca++) 135 { 136 if(ca)printf("\n"); 137 if(!build())printf("IMPOSSIBLE\n"); 138 else 139 { 140 int out[205][25]; 141 for(int i=1;i<=N;i++) 142 for(int j=FIR[i];j!=-1;j=NEXT[j]) 143 if(N<TO[j]&&TO[j]<=N+M) 144 out[i][TO[j]-N]=CAP[j^1]; 145 for(int i=1;i<=N;i++) 146 for(int j=1;j<=M;j++) 147 printf("%d%c",out[i][j]+l[i][j],j==M?‘\n‘:‘ ‘); 148 } 149 } 150 return 0; 151 }
标签:foo special ued meeting color site mat exist ber
原文地址:https://www.cnblogs.com/taozi1115402474/p/9646561.html