HDU 2732 Leapin' Lizards

题意

给你两个图,一个用0,1,2,3表示,一个用 L 或 . 表示。其中用L表示的图中,有L的位置表示有蜥蜴,没有L的位置表示没有蜥蜴。用数字表示的图中,数字表示当前位置柱子的高度,每次一个蜥蜴可以从一个柱子跳到距离d以内的另外一个柱子,每跳跃一次,当前柱子的高度就减一,问最后会有多少只蜥蜴被困在里面。

将柱子拆点,每个蜥蜴向其曼哈顿距离内点连边,跑最大流

代码

#include
#include
#include
#include
#include
#define For(i,j,k) for(int i=(j);i<=(int)k;i++)
#define Forr(i,j,k) for(int i=(j);i>=(int)k;i--)
#define Set(a,b) memset(a,b,sizeof(a))
#define Rep(i,u) for(int i=Begin[u],v=to[i];i;i=Next[i],v=to[i])
using namespace std;
const int N=810,M=7500,INF=0x3f3f3f3f;
template <class T>inline void read(T &x){
    x=0;char c=getchar();int f(0);
    while(c>'9'||c<'0')f|=(c=='-'),c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    x=f?-x:x;
}
template <class T>inline void chkmin(T &a,T b){a=a>b?b:a;}
template <class T>inline void chkmax(T &a,T b){a=aint Begin[N],Next[M<<1],to[M<<1],f[M<<1],e=1,n,m,d;
inline void add(int x,int y,int z){
    to[++e]=y,Next[e]=Begin[x],Begin[x]=e,f[e]=z;
}
struct isap{
    int s,t,gap[N],d[N],p[N],cur[N];
    #define Retr(u) for(u=t;u^s;u=to[p[u]^1])
    inline void init(){
        queue<int>q;
        For(i,1,t)d[i]=INF,gap[i]=0,cur[i]=Begin[i];
        gap[0]=1;d[t]=0;q.push(t);
        while(!q.empty()){
            int r=q.front();q.pop();
            Rep(i,r)
                if(f[i^1]&&d[v]>d[r]+1)
                    ++gap[d[v]=d[r]+1],q.push(v);
        }
    }
    inline int Augment(){
        int u,a=INF;
        Retr(u)chkmin(a,f[p[u]]);
        Retr(u)f[p[u]]-=a,f[p[u]^1]+=a;
        return a;
    }
    inline int Maxflow(int _s,int _t){
        int i,u=s=_s,flow=0;t=_t;
        init();
        while(d[s]if(u==t)flow+=Augment(),u=s;
            for(i=cur[u];i;i=Next[i])
                if(f[i]&&d[u]==d[to[i]]+1)break;
            if(!i){
                if(--gap[d[u]]==0)break;
                d[u]=t;cur[u]=Begin[u];
                Rep(i,u)
                    if(f[i])chkmin(d[u],d[v]+1);
                ++gap[d[u]];
                if(u^s)u=to[p[u]^1];
            }else cur[u]=i,p[u=to[i]]=i;
        }
        return flow;

    }
}F;
char ch[25];
char st[25][25];
struct node{
    int x,y,z;
    node(int x=0,int y=0,int z=0):x(x),y(y),z(z){}
}P[N];
inline bool can(node a,node b,int d){
    int l=abs(a.x-b.x)+abs(a.y-b.y);
    if(l<=d)return 1;
    return 0;
}
inline bool out(node a,int d){
    return a.x+d>n || a.x-d<1 || a.y+1+d>m || a.y-d<0;
}
inline void work(){
    int totz(0),totl(0);
    read(n),read(d);
    Set(Begin,0),e=1,m=0;
    For(i,1,n){
        scanf("%s",ch);
        if(!m)m=strlen(ch);
        For(j,0,m-1)
            if(ch[j]!='0')
                P[++totz]=node(i,j,ch[j]-'0');
    }
    For(i,1,n)
        scanf("%s",st[i]);
    int s_=totz*2+1,t_=s_+1;
    For(i,1,totz){
        add(i,i+totz,P[i].z),add(i+totz,i,0);
        For(j,1,totz)
            if(i!=j)
                if(can(P[i],P[j],d))
                    add(i+totz,j,P[i].z),add(j,i+totz,0);
        if(st[P[i].x][P[i].y]=='L')add(s_,i,1),add(i,s_,0),totl++;
        if(out(P[i],d))add(i+totz,t_,P[i].z),add(t_,i+totz,0);
    }
    int ans=totl-F.Maxflow(s_,t_);
    if(ans==0)
        printf("no ");
    else printf("%d ",ans);
    if(ans==1||ans==0)puts("lizard was left behind.");
    else puts("lizards were left behind.");
}
int main(){
    int T;
    read(T);
    For(i,1,T)  
        printf("Case #%d: ",i),work();
    return 0;
}

你可能感兴趣的:(hdu,网络流)