POJ 3498 March of the Penguins

来源:互联网 发布:mac怎么关闭加密文件夹 编辑:程序博客网 时间:2024/06/06 01:12

很基础的网络流问题

题目里面有很明显的提示,每个冰块有它原来的在它上面的企鹅数量,也有跳出企鹅的数量。很显然我们建图的时候就可以把原来的企鹅数量作为入边,跳出的作为出边,为了限制出边,可以考虑拆点。把i拆成i与i+n,边的容量是m,而i+n与从i可跳到的冰块连边,为了方便起见,这条边的容量可以赋成inf。

#include "cstdio"#include "vector"#include "queue"#include "cstring"#include "cmath"using namespace std;struct edge{int to,cap,rev;};#define max_v 210#define inf 111111#define eps 1e-10vector <edge> g[max_v];int level[max_v];int iter[max_v];void add_edge(int from,int to,int cap){g[from].push_back((edge){to,cap,(int)g[to].size()});g[to].push_back((edge){from,0,(int)g[from].size()-1});}void bfs(int s){memset(level,-1,sizeof(level));queue<int> que;level[s]=0;que.push(s);while(!que.empty()){    int v=que.front(); que.pop();    for(int i=0;i<g[v].size();i++){        edge &e=g[v][i];        if(e.cap>0&&level[e.to]<0){            level[e.to]=level[v]+1;            que.push(e.to);        }    }}}int dfs(int v,int t,int f){if(v==t)  return f;for(int &i=iter[v];i<g[v].size();i++){    edge &e=g[v][i];    if(e.cap>0&&level[v]<level[e.to]){        int d=dfs(e.to,t,min(f,e.cap));        if(d>0){            e.cap-=d;            g[e.to][e.rev].cap+=d;            return d;        }    }}return 0;}int max_flow(int s,int t){int flow=0;for(;;){    bfs(s);    if(level[t]<0)  return flow;    memset(iter,0,sizeof(iter));    int f;    while((f=dfs(s,t,inf))>0){ flow+=f;}}}struct point{    double x,y;    int n,m;}sa[111];double len(point a,point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}int map[111][111];int n;int sum;int cnt;void build(){    for(int i=0;i<2*n+5;i++)  g[i].clear();    for(int i=1;i<=n;i++)  add_edge(0,i,sa[i].n);    for(int i=1;i<=n;i++)  add_edge(i,n+i,sa[i].m);    for(int i=1;i<=n;i++){        for(int j=1;j<=n;j++){            if(map[i][j])  add_edge(n+i,j,inf);        }    }}int check(int c){    build();    if(max_flow(0,c)==sum)  return 1;    return 0;}int ans[111];int main(){    int t;    double d;    scanf("%d",&t);    while(t--){        sum=0;        cnt=0;        scanf("%d%lf",&n,&d);        for(int i=1;i<=n;i++){            scanf("%lf%lf%d%d",&sa[i].x,&sa[i].y,&sa[i].n,&sa[i].m);            sum+=sa[i].n;        }        memset(map,0,sizeof(map));        for(int i=1;i<=n;i++){            for(int j=i+1;j<=n;j++){                if(fabs(len(sa[i],sa[j])-d*d)<eps||d*d>len(sa[i],sa[j]))  map[i][j]=map[j][i]=1;            }        }        for(int i=1;i<=n;i++){            if(check(i))  ans[cnt++]=i;        }        if(cnt==0)  printf("-1\n");        else{            for(int i=0;i<cnt;i++){                if(i==0)  printf("%d",ans[i]-1);                else  printf(" %d",ans[i]-1);            }            printf("\n");        }    }}


0 0
原创粉丝点击