SGU 438 The Glorious Karlutka River =) 动态流 最大流

来源:互联网 发布:淘宝女装春装2015新款上市 编辑:程序博客网 时间:2024/06/15 21:46

把这题当动态流入门题来做了。
网上的题解都已经说的很清楚了。这里再强调一下几个特殊的点。

  1. 当跳动距离大于河宽时,直接输出1
  2. 每个点都需要拆点,当我们在两个不同点之间连边时,需要从一个点的上一秒拆出来的点走到另一点的这一秒的点。
  3. 连终点是把上一秒的这个点拆出来的点和终点相连,而和起点连的是这一秒的点。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <queue>#include <cmath>using namespace std;const int MAXN = 3e5;const double eps = 1e-8;const int MAXM = 1e7;const int INF = 0x3f3f3f3f;int head[MAXN],dis[MAXN],tol,n,m,w,d,x[MAXN],y[MAXN],lim[MAXN],src,det;struct Edge{    int to,cap,flow,nex;    Edge(int to,int cap,int flow,int nex):to(to),cap(cap),flow(flow),nex(nex) {}    Edge() {}}edge[MAXM];void init(){    memset(head,-1,sizeof head);    tol=0;}void addedge(int u,int v,int cap){    edge[tol]=Edge(v,cap,0,head[u]); head[u]=tol++;    edge[tol]=Edge(u,0,0,head[v]); head[v]=tol++;}int dcmp(double a,double b){    if (a-b>eps) return 1;    if (a-b<-eps) return -1;    return 0;}double dist(int i,int j){    return sqrt(1.0*(x[i]-x[j])*(x[i]-x[j]) + 1.0*(y[i]-y[j])*(y[i]-y[j]));}bool bfs(int s,int t){    memset(dis,-1,sizeof dis);    dis[s]=0;    queue<int> que;    que.push(s);    while (!que.empty())    {        int u=que.front();que.pop();        for (int i=head[u];~i;i=edge[i].nex)        {            int v=edge[i].to;            if (dis[v]==-1 &&edge[i].cap-edge[i].flow)            {                dis[v]=dis[u]+1;                if (v==t) return true;                que.push(v);            }        }    }    return false;}int dfs(int u,int t,int cap){    if (u==t) return cap;    int flow=0,f;    for (int i=head[u];~i;i=edge[i].nex)    {        int v=edge[i].to;        if (dis[v]==dis[u]+1 && edge[i].cap>edge[i].flow)        {            f=dfs(v,t,min(cap-flow,edge[i].cap-edge[i].flow));            edge[i].flow += f;            edge[i^1].flow -=f;            flow +=f ;            if (cap == flow )break;        }    }    if (!flow) dis[u]=-1;    return flow;}int dicnic(int s,int t){    int flow=0,a;    while (bfs(s,t))        while ( (a=dfs(s,t,INF)) >0)            flow+=a;    return flow;}int main(){    src=0;det=6000;    while (scanf("%d%d%d%d",&n,&m,&d,&w)!=EOF)    {        int cnt=0;        init();        for (int i=1;i<=n;i++)        {            scanf("%d%d%d",&x[i],&y[i],&lim[i]);        }        if (d>=w)        {            cout<<"1"<<endl;            continue;        }        int flow=0,t;        for (t=1;t<=n+m;t++)        {            for (int i=1;i<=n;i++)            {                if (y[i]<=d)                    addedge(0,t*200+i,INF);                if (w-y[i]<=d)                    addedge((t-1)*200+i+50,det,INF);                for (int j=1;j<=n;j++)                    if (i!=j && dcmp(dist(i,j),d)<=0)                        addedge((t-1)*200+i+50,t*200+j,INF);                addedge(t*200+i,t*200+i+50,lim[i]);            }            flow += dicnic(src,det);//            cout<<t<<" "<<flow<<endl;            if (flow >= m) break;        }        if (flow < m)            printf("IMPOSSIBLE\n");        else            printf("%d\n",t);    }    return 0;}