您的位置:首页 > 其它

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

2013-09-02 12:19 281 查看
题意:

给了两个(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 long
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: