当前位置: 代码迷 >> 综合 >> POJ 3498 网络流英文阅读题
  详细解决方案

POJ 3498 网络流英文阅读题

热度:5   发布时间:2024-01-20 20:28:27.0

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

题目大意:帝企鹅喜欢群居,现在有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;
}