Gems
zoj2332:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2332
题意:这一道题的题意,我看了很久,也没有看明白,最终还是理解错了。题目的意思是有n*m种石头,有n种形状,m种颜色。一个人对于每一种形状有一定的容忍度,另外一个人对于每一种颜色有一定容忍度,然后问你能把这些石头分给这两个人,使得每个人能够满意。
题解:每一种石头作为一个点,与源点连边,边的容量就是石头的数量,然后每一行作为一个点,对应每一种形状的,容量是INF,然后是每一列一个点,与宝石连接,INF,然后每个行与BF连接,就是每一种形状的容忍度,每一列与GF连接,就是每一种颜色的容忍度,然后BF,GF与汇点连接,INF。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<queue> 6 #define INF 100000000 7 using namespace std; 8 const int N=1205; 9 const int M=1000000; 10 struct Node{ 11 int v; 12 int f; 13 int next; 14 }edge[M]; 15 int n,m,u,v,cnt,sx,ex; 16 int head[N],pre[N]; 17 int mp[N][N],a1[N],a2[N]; 18 void init(){ 19 cnt=0; 20 memset(head,-1,sizeof(head)); 21 } 22 void add(int u,int v,int w){ 23 edge[cnt].v=v; 24 edge[cnt].f=w; 25 edge[cnt].next=head[u]; 26 head[u]=cnt++; 27 edge[cnt].f=0; 28 edge[cnt].v=u; 29 edge[cnt].next=head[v]; 30 head[v]=cnt++; 31 } 32 bool BFS(){ 33 memset(pre,0,sizeof(pre)); 34 pre[sx]=1; 35 queue<int>Q; 36 Q.push(sx); 37 while(!Q.empty()){ 38 int d=Q.front(); 39 Q.pop(); 40 for(int i=head[d];i!=-1;i=edge[i].next ){ 41 if(edge[i].f&&!pre[edge[i].v]){ 42 pre[edge[i].v]=pre[d]+1; 43 Q.push(edge[i].v); 44 } 45 } 46 } 47 return pre[ex]>0; 48 } 49 int dinic(int flow,int ps){ 50 int f=flow; 51 if(ps==ex)return f; 52 for(int i=head[ps];i!=-1;i=edge[i].next){ 53 if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){ 54 int a=edge[i].f; 55 int t=dinic(min(a,flow),edge[i].v); 56 edge[i].f-=t; 57 edge[i^1].f+=t; 58 flow-=t; 59 if(flow<=0)break; 60 } 61 62 } 63 if(f-flow<=0)pre[ps]=-1; 64 return f-flow; 65 } 66 int solve(){ 67 int sum=0; 68 while(BFS()) 69 sum+=dinic(INF,sx); 70 return sum; 71 } 72 int main() { 73 int T,k,temp,sum,d,t1,t2,t3,t4,tt=1; 74 scanf("%d",&T); 75 while(T--) { 76 scanf("%d%d",&n,&m); 77 init();sum=0; 78 for(int i=1;i<=n;i++) 79 for(int j=1;j<=m;j++){ 80 scanf("%d",&temp); 81 sum+=temp; 82 add(0,(i-1)*m+j,temp); 83 } 84 85 scanf("%d",&d); 86 for(int i=1;i<=d;i++){ 87 scanf("%d%d%d%d",&t1,&t2,&t3,&t4); 88 t2++;t4++; 89 add(t1*m+t2,t3*m+t4,INF); 90 add(t3*m+t4,t1*m+t2,INF); 91 } 92 for(int i=1;i<=n;i++){ 93 scanf("%d",&temp); 94 for(int j=1;j<=m;j++){ 95 add((i-1)*m+j,n*m+i,INF); 96 } 97 add(n*m+i,n*m+m+n+1,temp); 98 } 99 for(int i=1;i<=m;i++){ 100 scanf("%d",&temp); 101 for(int j=1;j<=n;j++){ 102 add((j-1)*m+i,n*m+n+i,INF); 103 } 104 add(n*m+n+i,n*m+m+n+2,temp); 105 } 106 add(n*m+n+m+1,n*m+n+m+3,INF); 107 add(n*m+n+m+2,n*m+n+m+3,INF); 108 sx=0,ex=n*m+n+m+3; 109 int td=solve(); 110 if(td==sum)printf("Yes\n"); 111 else 112 printf("No\n"); 113 } 114 return 0; 115 }