POJ 2711 - Leapin' Lizards 拆点构图最大流..

来源:互联网 发布:单页引导页源码 编辑:程序博客网 时间:2024/06/06 09:50

                题意:

                        给了两个(x,y)地图..其实是描述的一张图..第一张图说明图中的每个点至多有多少个lizard出去..第二张图说明哪些位置有lizard..现在告诉lizard每次的最远移动距离..而图中任意两点的距离为其曼哈顿距离...问能否让所有的lizard走出地图...

                题解:

                        这题和POJ 3498差不多了...一个点拆成"起点"和"终点"..“起点"到"终点"的流量为最大离开的lizard个数...而超级源点与每个有'L'点的"起点"做边.容量为1..而若一个点可以一步走出去..则其与超级汇点做边..容量为无穷大..然后根据各点能到达的情况做边..跑一次最大流找出最多能跑出去的lizard个数..用总数减去它就是答案..值得注意的是输出要看清..

 

Program:

#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#define MAXN 1005#define MAXM 2000005#define oo 1000000007#define ll long longusing namespace std;  struct Dinic    {           struct node         {                int c,u,v,next;         }edge[MAXM];         int ne,head[MAXN];         int cur[MAXN], ps[MAXN], dep[MAXN];         void initial()         {               ne=2;               memset(head,0,sizeof(head));          }         void addedge(int u, int v,int c)         {                edge[ne].u=u,edge[ne].v=v,edge[ne].c=c,edge[ne].next=head[u];               head[u]=ne++;               edge[ne].u=v,edge[ne].v=u,edge[ne].c=0,edge[ne].next=head[v];               head[v]=ne++;         }         int MaxFlow(int s,int t)         {                                    int tr, res = 0;               int i,j,k,f,r,top;               while(1)               {                      memset(dep, -1, sizeof(dep));                      for(f=dep[ps[0]=s]=0,r=1;f!= r;)                         for(i=ps[f++],j=head[i];j;j=edge[j].next)                           if(edge[j].c&&dep[k=edge[j].v]==-1)                           {                                 dep[k]=dep[i]+1;                                 ps[r++]=k;                                 if(k == t){  f=r; break;  }                           }                      if(dep[t]==-1) break;                      memcpy(cur,head,sizeof(cur));                      i=s,top=0;                      while(1)                      {                           if(i==t)                           {                                 for(tr=oo,k=0;k<top;k++)                                    if(edge[ps[k]].c<tr)                                       tr=edge[ps[f=k]].c;                                 for(k=0;k<top;k++)                                 {                                       edge[ps[k]].c-=tr;                                       edge[ps[k]^1].c+=tr;                                 }                                 i=edge[ps[top=f]].u;                                 res+= tr;                           }                           for(j=cur[i];cur[i];j=cur[i]=edge[cur[i]].next)                                if(edge[j].c && dep[i]+1==dep[edge[j].v]) break;                            if(cur[i])  ps[top++]=cur[i],i=edge[cur[i]].v;                            else                           {                                   if(!top) break;                                   dep[i]=-1;                                   i=edge[ps[--top]].u;                           }                     }               }               return res;        }  }T;char A[25][25],B[25][25]; int main() {             int n,m,d,i,j,ii,jj,s,e,x,sum,ans,C,cases=0;       scanf("%d",&C);      for (cases=1;cases<=C;cases++)       {              scanf("%d%d",&n,&d);              for (i=0;i<n;i++) scanf("%s",A[i]);              m=strlen(A[0]);              for (i=0;i<n;i++) scanf("%s",B[i]);              s=n*m*2+10,e=s+1,T.initial();              sum=0;              for (i=0;i<n;i++)                 for (j=0;j<m;j++)                 {                        x=i*m+j;                        if (A[i][j]!='0') T.addedge(x<<1,x<<1|1,A[i][j]-'0');                        if (B[i][j]=='L') T.addedge(s,x<<1,1),sum++;                        for (ii=0;ii<n;ii++)                           for (jj=0;jj<m;jj++)                              if (A[ii][jj]!='0' && abs(i-ii)+abs(j-jj)<=d)                                  T.addedge(x<<1|1,(ii*m+jj)<<1,oo);                          if (i-d<0 || i+d>=n || j-d<0 || j+d>=m) T.addedge(x<<1|1,e,oo);                 }              ans=sum-T.MaxFlow(s,e);              printf("Case #%d: ",cases);              if (!ans) printf("no");                  else  printf("%d",ans);              if (ans<=1)                        printf(" lizard was left behind.\n");                     else  printf(" lizards were left behind.\n");                 }       return 0;}