[SCOI2007]蜥蜴

来源:互联网 发布:网络储存硬盘 编辑:程序博客网 时间:2024/04/28 23:47

Description

在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。

Sample Input

5 8 20000000002000000003211000200000000000000..................LLLL..................

Sample Output

1

网络流,题目还行。
每一只蜥蜴的路径就是一条1的流,柱子高度减小相当于流量上限减小,然后就可以类比着构出网络流的图:
直接拆点,分成出点和入点。
将整个图的石柱的入点和出点连在一起,流量为该石柱的高度。
之后将合法石柱与附近的合法联接。
然后让可以到终点的合法石柱连到ed。
之后将st连到每只蜥蜴所处的石柱。

#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;struct node{    int x,y,c,next,other;}a[6110000];int len,last[1110000],st,ed;char map[25][25];struct nodd{    int x,y,c;}sz[110000];int szs,xys;bool vv[25][25];void ins(int x,int y,int c){    int k1,k2;    len++; k1=len;    a[len].x=x;a[len].y=y;a[len].c=c;    a[len].next=last[x]; last[x]=len;    len++; k2=len;    a[len].x=y;a[len].y=x;a[len].c=0;    a[len].next=last[y]; last[y]=len;    a[k1].other=k2;    a[k2].other=k1;}int list[1110000],head,tail,h[1110000];bool bfs(){    memset(h,0,sizeof(h));h[st]=1;    list[1]=st;head=1;tail=2;    while(head!=tail)    {        int x=list[head];        for(int k=last[x];k;k=a[k].next)        {            int y=a[k].y;            if(  a[k].c>0 &&  h[y]==0  )            {                h[y]=h[x]+1;                list[tail++]=y;            }        }        head++;    }    if(h[ed]>0) return true;    else return false;}int mymin(int x,int y){ return x<y?x:y;}int dfs(int x,int flow){    if(x==ed) return flow;    int tt,minf;    tt=0;    for(int k=last[x];k;k=a[k].next)    {        int y=a[k].y;           if(a[k].c>0&&h[y]==(h[x]+1)&&tt<flow)        {            minf=dfs(y,mymin(a[k].c,flow-tt));            tt+=minf;            a[k].c-=minf;a[a[k].other].c+=minf;        }    }    if(tt==0)h[x]=0;    return tt;}int main(){    int n,m,d;    scanf("%d%d%d",&n,&m,&d);    len=0;memset(last,0,sizeof(last));    szs=0;    for(int i=1;i<=n;i++)    {        for(int j=0;j<=m;j++)        {            scanf("%c",&map[i][j]);            if(map[i][j]>'0'&&map[i][j]<='3')            {                szs++;sz[szs].x=i,sz[szs].y=j;                sz[szs].c=map[i][j]-'0';            }        }    }    for(int i=1;i<=n;i++)    {        for(int j=0;j<=m;j++)        {            scanf("%c",&map[i][j]);            if(map[i][j]=='L')            {                xys++;                vv[i][j]=1;            }        }    }    st=0;ed=szs*2+1;    for(int i=1;i<=szs;i++)ins(i,i+szs,sz[i].c);    for(int i=1;i<=szs;i++)    {        for(int j=1;j<=szs;j++)if(i!=j)        {            if(abs(sz[i].x-sz[j].x)+abs(sz[i].y-sz[j].y)<=d)            {                ins(i+szs,j,999999999);            }        }    }    for(int i=1;i<=szs;i++)    {        if((n-sz[i].x<d||sz[i].x<=d)||(m-sz[i].y<d||sz[i].y<=d))            ins(i+szs,ed,999999999);    }    for(int i=1;i<=szs;i++)if(vv[sz[i].x][sz[i].y])ins(st,i,1);    int ans=0;    while(bfs())    {        ans+=dfs(st,999999999);    }    printf("%d\n",xys-ans);    return 0;}
0 0