现在的位置: 首页 > 综合 > 正文

POJ 3498 网络流英文阅读题

2013年01月28日 ⁄ 综合 ⁄ 共 1963字 ⁄ 字号 评论关闭

一如既往的,我又把题意看错了....

题目大意:帝企鹅喜欢群居,现在有N块浮冰,给定企鹅跳跃能力D,给定Xi,Yi作为二维坐标,Ni为该浮冰上有多少企鹅,Mi为该浮冰上有多少企鹅离开后会破裂。问是否所有企鹅能否完成群居。

5 3.5
1 1 1 1
2 3 0 1
3 5 1 1
5 1 1 1
5 4 0 1

如上面这组数据,0,3,4浮冰上有企鹅,每块浮冰都能让一只企鹅离开。

构图还是很好的。因为每块浮冰有离开企鹅数量的上限,所以这块浮冰到其他可达浮冰的流量是有限制的,这个限制就是离开企鹅的数量。

比较直观不说了。我的做法是枚举聚合点,在聚合点连一条无穷大的容量边至汇点。

我看错的题意:把浮冰跳离企鹅的上限看成了,浮冰多少time后消失... 太丢脸了....

这样我死活没构出图来。只想到了一个100*200个点的图= =

谁知道告诉我一下.

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

int N,s,t,tot;
double D;
struct node
{
 	int x,y;   
}p[MN];
int maze[MN][MN],map[MN][MN],pre[MN],dis[MN],gap[MN],cur[MN];

double dist( node a,node b ){
 	   return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

void setG()
{
 	 CC(maze);tot=0;
 	 scanf("%d%lf",&N,&D);
 	 s=0;t=2*N+1;
   	 FF(i,1,N+1){
   	    scanf("%d%d",&p[i].x,&p[i].y);
   	    scanf("%d",&maze[s][i]);
   	    tot+=maze[s][i];
   	    scanf("%d",&maze[i][i+N]);
	 }
	 FF(i,1,N+1)FF(j,i+1,N+1)
	 if( dist(p[i],p[j])<=D*D){
	 	 maze[i+N][j]=INF;
	  	 maze[j+N][i]=INF;
	 }/*
	 for( int i=0;i<=t;i++ )
	 {
	  	  for( int j=0;j<=t;j++ )
	 	  	   printf( "%d ",maze[i][j] );
	 	  printf( "\n" );
     }
     getchar();
     getchar();*/
}

void initG()
{
 	 FF(i,s,t+1)FF(j,s,t+1)
 	 map[i][j]=maze[i][j];
}

bool sap( int ti )
{
 	 map[ti][t]=INF;
 	 CC(cur),CC(pre),CC(gap),CC(dis);
 	 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( map[u][v]&&dis[u]==dis[v]+1 )
		 	{
	 	 	 	cur[u]=v;
			 	pre[v]=u;
		 	 	checkmin( aug,map[u][v] );
 		  		u=v;
	 	 		if( v==t )
		 	 	{  
				  	maxflow+=aug;
				  	for( u=pre[u];v!=s;v=u,u=pre[u] )
				  	{ 
					  	 map[u][v]-=aug;
					  	 map[v][u]+=aug;
				 	}  
			 	 	aug=-1;
  		 		}
	  		 	goto loop;
			}
			int mind=t;
			for( int v=0;v<=t;v++ )
			if( map[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];
      }
      //printf( "%d %d\n",ti,maxflow );
      //getchar();
      if( maxflow==tot )return true;
      else return false;
}

int main()
{
 	int T;
 	scanf( "%d",&T );
 	while( T-- )
 	{
	 	   setG();
	 	   int rec[MN],len=0;
	 	   FF( i,1,N+1 ){
		   	   initG();
  	   	   	   if( sap(i) )
  	   	   	   	   rec[len++]=i;
  		   }
  	   	   if( len>0 ){
		   	   printf( "%d",rec[0]-1 );
			   FF(i,1,len) printf( " %d",rec[i]-1 );
			   printf( "\n" );  
   		   }
   		   else 
   		   printf( "-1\n");
  	}
  	return 0;
}

抱歉!评论已关闭.