poj 3498 网络流 拆点
来源:互联网 发布:java哪个老师出名 编辑:程序博客网 时间:2024/06/05 17:24
题意:某个冰块上有a只企鹅,总共可以跳出去b只,问是否可能所有的企鹅都跳到某一块冰块上,输出所有的可能的冰块的编号。
由于每个点只能跳出去m只企鹅,所以要拆点
假如不拆点,一个点到另一个点可能会跳多于m只企鹅
通过拆点后u->u'间的容量来完成题目的要求(对点的一些限制)
建图:i->i+n 容量为m i+n->j容量为INF
新建源点s,s->i的容量为i点企鹅的个数
然后枚举汇点求最大流就可以判断某个点是否符合条件
View Code
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<algorithm>
using namespace std;
const double eps = 1e-8;
const int MAX=10000;
const int INF=1000000000;
struct point {
int a,b;
double x,y;
}p[200];
double D;
double Dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct
{
int v,c,next;
}edge[1000000];
int E,head[MAX];
int gap[MAX],cur[MAX];
int pre[MAX],dis[MAX];
void add_edge(int s,int t,int c,int cc)
{
edge[E].v=t; edge[E].c=c;
edge[E].next=head[s];
head[s]=E++;
edge[E].v=s; edge[E].c=cc;
edge[E].next=head[t];
head[t]=E++;
}
int min(int a,int b){return (a==-1||b<a)?b:a;}
int SAP(int s,int t,int n)
{
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
int i;
for(i=0;i<n;i++)cur[i]=head[i];
int u=pre[s]=s,maxflow=0,aug=-1,v;
gap[0]=n;
while(dis[s]<n)
{
loop: for(i=cur[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(edge[i].c>0&&dis[u]==dis[v]+1)
{
aug=min(aug,edge[i].c);
pre[v]=u;
cur[u]=i;
u=v;
if(u==t)
{
for(u=pre[u];v!=s;v=u,u=pre[u])
{
edge[cur[u]].c-=aug;
edge[cur[u]^1].c+=aug;
}
maxflow+=aug;
aug=-1;
}
goto loop;
}
}
int mindis=n;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(edge[i].c>0&&dis[v]<mindis)
{
cur[u]=i;
mindis=dis[v];
}
}
if((--gap[dis[u]])==0)break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return maxflow;
}
int main()
{
int n,i,a,b,j,t;
scanf("%d",&t);
while(t--)
{
int sum=0;
memset(head,-1,sizeof(head));
E=0;
int s=0,t=n+1;
scanf("%d%lf",&n,&D);
for(i=1;i<=n;i++)
{
scanf("%lf%lf%d%d",&p[i].x,&p[i].y,&p[i].a,&p[i].b);
sum+=p[i].a;
add_edge(s,i,p[i].a,0);
add_edge(i,i+n,p[i].b,0);
}
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
if(Dis(p[i],p[j])<D)
{
add_edge(n+i,j,INF,0);
add_edge(n+j,i,INF,0);
}
}
}
int flag=0;
for(i=1;i<=n;i++)
{
if(SAP(s,i,2*n+1)==sum)
{
printf("%d ",i-1);
flag=1;
}
for(j=0;j<E;j+=2) edge[j].c+=edge[j^1].c,edge[j^1].c=0; //每次流完之后恢复原图
}
if(!flag) printf("-1\n");
else printf("\n");
}
}
- poj 3498 网络流 拆点
- Poj 3281 Dining (拆点网络流)
- poj 3281 (拆点网络流)
- POJ 3281 Dining 拆点网络流
- poj 3281(网络流+拆点)
- POJ 3281 Dining (拆点+ 网络流)
- poj 3498(满足点容量限制的网络流)
- 【floyd+拆点+二分答案+网络流】POJ 2391
- poj 2391 网络流 拆点 Floyd最短路
- poj 2391 网络流 二分 最短路 拆点
- poj 2391 Ombrophobic Bovines 【floyd + 二分 + 拆点网络流】
- poj 2391 二分 拆点 最大值最小值网络流
- 网络流( ISAP + 拆点 )——Dining ( POJ 3281 )
- POJ 3436 ACM Computer Factory(网络流 拆点)
- 【POJ 3281 Dining】& 网络流Dinic & 拆点
- 【POJ 3436 ACM Computer Factory】网络流 & 拆点 & Dinic
- POJ 3498 拆点 最大流
- poj 3498(最大流+拆点)
- hdu 3879 Base Station 网络流 最大权闭合图
- codeforces 118E Bertown roads 边双连通
- codeforces 160D Edges in MST
- 字典树 + DP
- 关于异步,同步,阻塞与非阻塞
- poj 3498 网络流 拆点
- codeforces 113 166B 凸包 计算几何
- poj 2284 That Nice Euler Circuit 计算几何
- 线段相交 直线相交 模板
- poj 2002 哈希函数的设计
- hdu 1496 哈希
- poj 2411 状态压缩DP 铺砖块
- 最小费用最大流模板 poj 2135
- hdu 1853 费用流