POJ 2112 网络流英文阅读题

这题的题意佷坑爹啊。。。虽说是很明显的二分题。

说有K个奶牛机编号1-K,有C头奶牛,编号k+1-K+C这样形成了K+C阶的距离矩阵。每台奶牛机可以处理T只奶牛

开始呢... 只把机器和奶牛连了边,机器与奶牛的边全部去掉了... 无限WA...

后来想.. 如果流通过机器之间传到奶牛呢= =!!!有剩余流就可以做到了!

顿悟,狂敲,交... 无限WA....

后来看了看题,机器之间的流不算流啊... 只要牛进入机器产奶就行了= =,距离只是个过程啊.. 相当于转移过程,这不是流啊...

然后... 用floyd把最短路构建出来,因为最短路嘛,一定会比单边的长...但是... 这个边好像是和诶.... 不是单边诶... 难道说 莫名其妙的AC了= =

#include<iostream>
#include<cstdio>
#include<string>
#define MN 255
#define INF INT_MAX>>2
using namespace std;

struct edge{
   int len,cap;
}map[MN][MN];
int que[MN],pre[MN],vis[MN],a[MN];
int K,C,M,s,t,l,r,ans;

void setG()
{
 	 int i,j,k;
 	 l=1;r=200000;
 	 s=0;t=K+C+1;
 	 memset( map,0,sizeof(map) );
 	 for( i=1;i<=K+C;i++ )
 	 for( j=1;j<=K+C;j++ ){
	  	  scanf( "%d",&map[i][j].len );
	  	  if( map[i][j].len==0 )
	  	  	  map[i][j].len=INF;
	 }
	 for( k=1;k<=K+C;k++ )
	 for( i=1;i<=K+C;i++ )
	 for( j=1;j<=K+C;j++ )
	 	  if( map[i][j].len>map[i][k].len+map[k][j].len )
	 	  	  map[i][j].len=map[i][k].len+map[k][j].len;
}

void initG( int len )
{
 	 int i,j;ans=0;
 	 for( i=0;i<=K+C+1;i++ )
 	 for( j=0;j<=K+C+1;j++ )
 	 	  map[i][j].cap=0;
 	 for( i=1;i<=K;i++ )
 	 for( j=K+1;j<=K+C;j++ )
	  	  map[i][j].cap=map[i][j].len<=len?1:0;
 	 for( i=1;i<=K;i++ )
	 	  map[s][i].cap=M;
  	 for( i=K+1;i<=K+C;i++ )
  	 	  map[i][t].cap=1;
}

bool bfs( int len )
{
 	 int head=0,foot=0;
 	 memset( vis,0,sizeof(vis) );
	 que[foot++]=s;vis[s]=true;a[s]=INT_MAX;
	 while( head<foot )
	 {
	  		int u=que[head++];
	  		for( int i=0;i<=t;i++ )
	  		{
			 	 if( !vis[i]&&map[u][i].cap )
			 	 {
				  	 vis[i]=true;
				  	 que[foot++]=i;
				  	 pre[i]=u;
				  	 a[i]=min( a[u],map[u][i].cap );
				  	 if( i==t )return true;
	 			 }
 	 	 	}
	 }
 	 return false;
}

bool work(int len)
{
 	 int m;
 	 while( bfs(len) ){
	  		m=t;
	  		ans+=a[t];
	  		while( m!=s ){
			 	   map[pre[m]][m].cap-=a[t];
			 	   map[m][pre[m]].cap+=a[t];
			 	   m=pre[m];
 	   		}
	 }
	 if( ans==C ) return true;
	 else return false;
}

int main()
{
 	while( scanf("%d%d%d",&K,&C,&M)!=EOF )
 	{
	 	   int mid;
	 	   setG();
	 	   while( (mid=(l+r)/2)&&l<r ){
		   		  initG(mid);
		   		  if( work(mid) ) r=mid;
				  else l=mid+1;
   		   }
   		   printf( "%d\n",mid );
  	}
  	return 0;
}


你可能感兴趣的:(POJ 2112 网络流英文阅读题)