SGU 438 動態流

來源:互聯網
上載者:User

題意:寬W的河面上有N個垃圾堆,每個垃圾堆只能站C人。河對岸有M個人,他們想藉著垃圾堆跳著過河,當然,如果河比較窄,可以直接跳過河。每個人跳躍一次最多可以跳D遠,問那些人過河的最短時間。

做法:此題不可以用費用流做,因為,每個人完全可以中途站在垃圾堆上,然後再跳過去。所以用了動態流的方法,把圖按照時間軸,分成一層一層的。這樣就先枚舉時間,然後用最大的手法做題。參考了大牛的做法,學了一些宏函數的定義。

#include<stdio.h>#include<string.h>#define eps 1e8#define LMT 55#define T(x,i) ((x)+(i-1)*50)//在每一個時間加入的不同點。#define CH(x)  ((x)+5000)#define tt 11274//一開始tt定義錯誤,陷入無限迴圈typedef struct{    int x,y;}node;typedef struct{    int u,v,next,c;}line;node nod[LMT*205];line e[(LMT*LMT+LMT)*205];int next[LMT*205],cap[LMT],lev[LMT*205],q[LMT*205],l[LMT*205];bool mat[LMT][LMT];int all,n,m,d,w;int test(int a,int b){    return (nod[a].x-nod[b].x)*(nod[a].x-nod[b].x)+     (nod[a].y-nod[b].y)*(nod[a].y-nod[b].y)<=d*d;}void insert(int u,int v,int c){    e[all].u=u;    e[all].v=v;    e[all].c=c;    e[all].next=next[u];    next[u]=all++;    e[all].u=v;    e[all].v=u;    e[all].c=0;    e[all].next=next[v];    next[v]=all++;}int bfs(int s,int t){    int u,v,x,head,tail;    memset(lev,0,sizeof(lev));    head=tail=0;    q[tail++]=s;lev[s]=1;    while(head<tail)    {        u=q[head++];        for(x=next[u];x!=-1;x=e[x].next)        {            v=e[x].v;            if(lev[v]==0&&e[x].c>0)            {                lev[v]=lev[u]+1;                q[tail++]=v;            }        }    }    return lev[t]!=0;}int dfs(int s,int t){    int u,v,x,top=0,ret=0;    q[top++]=s;    while(top>0)    {        u=q[top-1];        if(u==t)        {            int back,i,min=eps+10;            for(i=1;i<top;i++)            {                x=l[q[i]];             if(min>e[x].c)              {                x=l[q[i]];                min=e[x].c;                back=i;               }            }            ret+=min;            for(i=1;i<top;i++)            {                x=l[q[i]];                e[x].c-=min;                e[x^1].c+=min;            }            top=back;        }        else        {            for(x=next[u];x!=-1;x=e[x].next)            {                v=e[x].v;                if(lev[v]==lev[u]+1&&e[x].c>0)                {                    q[top++]=v;                    l[v]=x;                    break;                }            }            if(x==-1)            {                lev[u]=0;                top--;            }        }    }    return ret;}int dinic(int s,int t){    int ret=0;    while(bfs(s,t))      ret+=dfs(s,t);    return ret;}int main(){    int i,j,k,get=0,s,t;    scanf("%d%d%d%d",&n,&m,&d,&w);    memset(mat,0,sizeof(mat));    memset(next,-1,sizeof(next));    all=0;    s=0;t=tt;    for(i=1;i<=n;i++)    scanf("%d%d%d",&nod[i].x,&nod[i].y,&cap[i]);    for(i=1;i<=n;i++)      for(j=i+1;j<=n;j++)      if(test(i,j))        mat[i][j]=mat[j][i]=1;      if(d>=w)      {          printf("1\n");          return 0;      }      for(i=1;i<=n+m;i++)      {          for(j=1;j<=n;j++)          {              insert(T(j,i),CH(T(j,i)),cap[j]);              if(nod[j].y-d<=0)              insert(s,T(j,i),eps);              if(nod[j].y+d>=w)              insert(CH(T(j,i)),t,eps);              for(k=1;k<=n;k++)              if(mat[j][k])                insert(CH(T(j,i)),T(k,i+1),eps);//跳一次需要一秒,所以i時刻的點只可與i+1時刻的相連。          }          get+=dinic(s,t);          if(get>=m)break;      }      if(get<m)printf("IMPOSSIBLE\n");      else printf("%d\n",i+1);      return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.