poj 3498(March of the Penguins)

来源:互联网 发布:为什么程序员工资40万 编辑:程序博客网 时间:2024/06/06 00:18

题目链接:http://poj.org/problem?id=3498

题意简述:有n个冰块每个冰块上有ni只企鹅,并且每个冰块允许跳出的次数为mi,判定所有的企鹅能不能够跳到一块冰块上去,当冰块之间的距离小于等于d时企鹅才能从一个冰块跳到另一个冰块,若能所有企鹅能够跳到同一个冰块上,那么输出这些冰块(注意这里输出的时候是以0为参考),若没有这样的冰块满足条件则输出-1

自己不入流的分析方法:每个冰块上的企鹅,要流到一个特定的冰块上,每个冰块限制了能够流出的企鹅数,那么我们就可以这样建图新建源点s ,将冰块拆点u、u‘ ,s到u的权值为冰块上初始的企鹅数,u-u’的权值为该冰块允许流出的企鹅数,最后枚举冰块作为汇点


代码:

#include<iostream>#include<cstdio>#include <cstring>using namespace std;const int inf=0x3f3f3f3f;const int N = 210;const int E = 40000;struct node{int x,y,c,w,nxt;}edge[E];struct node1{double x, y;int n, m;}a[110];int harsh[N];int e,head[N];int dep[N],que[N],cur[N];void addedge(int u,int v,int c){edge[e].x=u;edge[e].y=v;edge[e].w=0;edge[e].nxt=head[u];edge[e].c=c;head[u]=e++;edge[e].x=v;edge[e].y=u;edge[e].w=0;edge[e].nxt=head[v];edge[e].c=0;head[v]=e++;}int maxflow(int n,int s,int t){int i,j,k,front,rear,top,min,res=0;while(1){for(i=0;i<=2*n;i++)   if(harsh[i]==1)   dep[i]=-2;    else dep[i]=-1;front=0;rear=0;que[rear++]=s;dep[s]=0;while(front!=rear){i=que[front++];for(j=head[i];j!=-1;j=edge[j].nxt)if(edge[j].c>edge[j].w&&dep[edge[j].y]==-1){dep[edge[j].y]=dep[i]+1;que[rear++]=edge[j].y;}}if(dep[t]==-1)break;memcpy(cur,head,sizeof(head)); for(i=s,top=0;;){if(i==t){min=inf;for(k=0;k<top;k++)if(min>(edge[que[k]].c-edge[que[k]].w)){min=edge[que[k]].c-edge[que[k]].w;front=k;}for(k=0;k<top;k++){edge[que[k]].w+=min;edge[que[k]^1].w-=min;}res+=min;i=edge[que[top=front]].x;}for(j=cur[i];cur[i]!=-1;j=cur[i]=edge[cur[i]].nxt)if(dep[edge[j].y]==dep[i]+1&&edge[j].c>edge[j].w)break;if(cur[i]!=-1){que[top++]=cur[i];i=edge[cur[i]].y;}else{if(top==0)break;dep[i]=-1;i=edge[que[--top]].x;}}}return res;}double dis(int i, int j){return (a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y -a[j].y)*(a[i].y-a[j].y);}int main (){int t;double d;int sum,n,i,j;scanf("%d",&t);while(t--){scanf("%d%lf",&n,&d);sum=0;for(i=1;i<=n;i++){scanf("%lf%lf%d%d",&a[i].x,&a[i].y,&a[i].n,&a[i].m);sum+=a[i].n;}        memset(head,-1,sizeof(head));e = 0;for(i=1;i<=n;i++){addedge(0,i,a[i].n);addedge(i,i+n,a[i].m);}        for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)if(dis(i,j)<=d*d){addedge(n+i,j,inf);addedge(j+n,i,inf);}memset(harsh,0,sizeof(harsh));int tag = 0;for(i=1;i<=n;i++){harsh[i+n]=1;int flow = maxflow(n,0,i);if(flow==sum){tag = 1;printf("%d ",i-1);}harsh[i+n]=0;for(j=0;j<e;j++)    edge[j].w=0;}if(tag==0)printf("-1\n");else printf("\n");}return 0;}