HDU 2732 Leapin' Lizards

題意

給你兩個圖,一個用0,1,2,3表示,一個用 L 或 . 表示。其中用L表示的圖中,有L的位置表示有蜥蜴,沒有L的位置表示沒有蜥蜴。用數字表示的圖中,數字表示當前位置柱子的高度,每次一個蜥蜴可以從一個柱子跳到距離d以內的另外一個柱子,每跳躍一次,當前柱子的高度就減一,問最後會有多少隻蜥蜴被困在裏面。

將柱子拆點,每個蜥蜴向其曼哈頓距離內點連邊,跑最大流

代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#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=a<b?b:a;}
int 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]<t){
            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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章