您的位置:首页 > 其它

poj 3498(枚举加最大流dinic)

2011-10-01 12:23 295 查看
这个题需要自己建一个超级源点,建边 s -> i -> i ' ; s->i 容量为 i 点企鹅的数量,i到 i ' 容量为能跳多少次,然后枚举到每一个点的最大流,如果等于企鹅的总数,记录这个点。。最后把所有能到达的点从小到大输出即可。。。。。

这里我刚开始的数组小了。。各种tle。。。。提醒一下吧。。。。

#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
using namespace std;
const int inf=1<<30;
const int maxn=100000;
#define cc(m,v) memset(m,v,sizeof(m))
struct node{
int u,v,f,next;
}edge[maxn];
int head[220],p,lev[220],cur[220];
int que[maxn];
void ainit(){
p=0,cc(head,-1);
}
bool bfs(int s,int t){
int i,u,v,qin=0,qout=0;
cc(lev,0),lev[s]=1,que[qin++]=s;
while(qout!=qin){
u=que[qout++];
for(i=head[u];i!=-1;i=edge[i].next)
if(edge[i].f>0 && lev[v=edge[i].v]==0){
lev[v]=lev[u]+1,que[qin++]=v;
if(v==t) return 1;
}
}
return lev[t];
}
int dinic(int s,int t){
int i,k,u,qin,f;
int flow=0;
while(bfs(s,t)){
memcpy(cur,head,sizeof(head));
u=s,qin=0;
while(1){
if(u==t){
for(k=0,f=inf;k<qin;k++)
if(edge[que[k]].f<f)
f=edge[que[i=k]].f;
for(k=0;k<qin;k++)
edge[que[k]].f-=f,edge[que[k]^1].f+=f;
flow+=f,u=edge[que[qin=i]].u;
}
for(i=cur[u];cur[u]!=-1;i=cur[u]=edge[cur[u]].next)
if(edge[i].f>0 && lev[u]+1==lev[edge[i].v]) break;
if(cur[u]!=-1)
que[qin++]=cur[u],u=edge[cur[u]].v;
else{
if(qin==0) break;
lev[u]=-1,u=edge[que[--qin]].u;
}
}
}
return flow;
}
void addedge(int u,int v,int f){
edge[p].u=u,edge[p].v=v,edge[p].f=f,edge[p].next=head[u],head[u]=p++;
edge[p].u=v,edge[p].v=u,edge[p].f=0,edge[p].next=head[v],head[v]=p++;
}
int main(){
int n,i,j,s,cas,sum,flag;
int ans[110],m,v,x[110],y[110];
double len;
scanf("%d",&cas);
while(cas--){
scanf("%d%lf",&n,&len);
ainit();
for(i=0,s=n<<1,sum=0;i<n;i++){
scanf("%d%d%d%d",&x[i],&y[i],&m,&v);
if(m) addedge(s,i,m),sum+=m;
addedge(i,i+n,v);
}
len=len*len;
for(i=0;i<n;i++) for(j=i+1;j<n;j++)
if(pow((double)x[i]-x[j],2)+pow((double)y[i]-y[j],2)<=len)
addedge(i+n,j,inf),addedge(j+n,i,inf);
for(i=0,flag=0;i<n;i++){
for(j=0;j<p;j+=2) edge[j].f+=edge[j^1].f,edge[j^1].f=0;
ans[i]=(dinic(s,i)==sum),flag+=ans[i];
}
if(!flag) printf("-1");
else{
for(i=0;i<n;i++) if(ans[i])
printf("%d ",i);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: