您的位置:首页 > 理论基础 > 计算机网络

ZOJ 2332 网络流英文阅读题

2012-04-12 21:53 302 查看
题目大意:

某人有很多宝石,各种颜色和形状,该人有超能力能改变宝石,使之变化一种颜色及形状。该人要送宝石给女友,他忍受的每种形状的宝石有上限,女友忍受的每种颜色的宝石有上限。求能否使得该人送宝石给女友,使得两人都满意?



思路:

本来我的思路是错的。如下面第一个代码,我这么写:

BF先让自己尽量忍受同形状的宝石,再将不能忍受的流向女友,当自己可以满流的时候,也就是自己完全能忍受,女友能把自己不能忍受的宝石全部吸收,这样就是一个符合条件的了。但是,我的这种思路是错的,因为,再初始流的时候,BF就可以把宝石变化,使得女友尽可能的接受,我的思路中却没有这一步,直接把他流向女友了。

其实题目可以这么做:

一堆宝石,分给BF与GF,BF,GF都有忍受极限,也就是容量。当宝石可以分完的时候,不就是Yes了吗!这么想,构图出来,1Y.

#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstdlib>
#define MN 230
#define INF 0x00FFFFFF
#define CC(what) memset( what,0,sizeof(what) )
#define FF(i,M) for( int i=0;i<M;i++ )
template<class T> void inline checkmin( T&a,T b ){ if( a>b||a==-1 ) a=b; }
using namespace std;

int R,C,s,t;
int m[11][11],maze[MN][MN];
int cntR[11],cntC[11],limR[11],limC[11];
void setG()
{
int r1,c1,r2,c2,u,v,k;
CC(cntR),CC(cntC),CC(maze),CC(limR),CC(limC);
scanf( "%d%d",&R,&C );
FF(i,R)FF(j,C){
scanf( "%d",&m[i][j] );
cntR[i]+=m[i][j];
cntC[j]+=m[i][j];
}
scanf( "%d",&k );
FF(i,k){
scanf( "%d%d%d%d",&r1,&c1,&r2,&c2 );
u=R+C+1+r1*C+c1;
v=R+C+1+r2*C+c2;
maze[u][v]=maze[v][u]=INF;
}
FF(i,R) scanf( "%d",&limR[i] );
FF(i,C) scanf( "%d",&limC[i] );
s=0;t=R+C+R*C+1;
FF(i,R)
if( cntR[i]-limR[i]>0 )
maze[s][i+1]=cntR[i]-limR[i];
FF(i,C) maze[R+1+i][t]=limC[i];
FF(i,R) FF(j,C){
v=R+C+1+i*C+j;
maze[i+1][v]=INF;
maze[v][R+j+1]=INF;
}
}

int cur[MN],pre[MN],dis[MN],gap[MN];
int sap()
{
CC(cur),CC(dis),CC(gap);
int u=pre[s]=s,maxflow=0,aug=-1;
gap[0]=t+1;
while( dis[s]<=t ){
loop:
for( int v=cur[u];v<=t;v++ )
if( maze[u][v]&&dis[u]==dis[v]+1 )
{
cur[u]=v;
checkmin( aug,maze[u][v] );
pre[v]=u;
u=v;
if( v==t )
{
maxflow+=aug;
for( u=pre[u];v!=s;v=u,u=pre[u] )
{
maze[u][v]-=aug;
maze[v][u]+=aug;
}
aug=-1;
}
goto loop;
}
int mind=t;
for( int v=0;v<=t;v++ )
if( maze[u][v]&&mind>dis[v] )
{
cur[u]=v;
mind=dis[v];
}
if( --gap[dis[u]]==0 )break;
gap[dis[u]=mind+1]++;
u=pre[u];
}
return maxflow;
}

bool work()
{
int KK=0;
FF(i,R)
if( cntR[i]-limR[i]>0 )
KK+=cntR[i]-limR[i];
if( KK==sap() ) return true;
else return false;
}

int main()
{
int T;
scanf( "%d",&T );
while( T-- )
{
setG();
if( work() ) printf( "Yes\n" );
else printf( "No\n" );
//getchar();
}
return 0;
}


#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstdlib>
#define MN 230
#define INF 0x00FFFFFF
#define CC(what) memset( what,0,sizeof(what) )
#define FF(i,M) for( int i=0;i<M;i++ )
template<class T> void inline checkmin( T&a,T b ){ if( a>b||a==-1 ) a=b; }
using namespace std;

int R,C,s,t,total;
int m[11][11],maze[MN][MN];
int cntR[11],cntC[11],limR[11],limC[11];
void setG()
{
int r1,c1,r2,c2,u,v,k;
CC(maze);
scanf( "%d%d",&R,&C );
s=0;t=R+C+R*C+3;
int BF=R+C+R*C+1,GF=R+C+R*C+2;
total=0;
FF(i,R)FF(j,C){
u=R+C+1+i*C+j;
scanf( "%d",&maze[s][u] );
total+=maze[s][u];
//cntR[i]+=m[i][j];
//cntC[j]+=m[i][j];
}
scanf( "%d",&k );
FF(i,k){
scanf( "%d%d%d%d",&r1,&c1,&r2,&c2 );
u=R+C+1+r1*C+c1;
v=R+C+1+r2*C+c2;
maze[u][v]=maze[v][u]=INF;
}
FF(i,R) scanf( "%d",&maze[i+1][BF] );
FF(i,C) scanf( "%d",&maze[R+i+1][GF] );
FF(i,R) FF(j,C){
v=R+C+1+i*C+j;
maze[v][i+1]=INF;
maze[v][R+j+1]=INF;
}
maze[BF][t]=maze[GF][t]=INF;
}

int cur[MN],pre[MN],dis[MN],gap[MN];
int sap()
{
CC(cur),CC(dis),CC(gap);
int u=pre[s]=s,maxflow=0,aug=-1;
gap[0]=t+1;
while( dis[s]<=t ){
loop:
for( int v=cur[u];v<=t;v++ )
if( maze[u][v]&&dis[u]==dis[v]+1 )
{
cur[u]=v;
checkmin( aug,maze[u][v] );
pre[v]=u;
u=v;
if( v==t )
{
maxflow+=aug;
for( u=pre[u];v!=s;v=u,u=pre[u] )
{
maze[u][v]-=aug;
maze[v][u]+=aug;
}
aug=-1;
}
goto loop;
}
int mind=t;
for( int v=0;v<=t;v++ )
if( maze[u][v]&&mind>dis[v] )
{
cur[u]=v;
mind=dis[v];
}
if( --gap[dis[u]]==0 )break;
gap[dis[u]=mind+1]++;
u=pre[u];
}
return maxflow;
}

bool work()
{
if( total==sap() ) return true;
else return false;
}

int main()
{
int T;
scanf( "%d",&T );
while( T-- )
{
setG();
if( work() ) printf( "Yes\n" );
else printf( "No\n" );
//getchar();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络 c sap