一如既往的,我又把题意看错了....
题目大意:帝企鹅喜欢群居,现在有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;
}