bzoj 1066蜥蜴

来源:互联网 发布:网络编辑前景分析 编辑:程序博客网 时间:2024/05/16 11:04

作为在bzoj上的第一题,感觉很伤233
这里写图片描述
这里写图片描述
第一道不是板子的最大流
这个建边要用到点
石柱的高度其实就是能经过蜥蜴的个数
将石柱拆分成两个点一个入点,一个出点,其容量就是石柱的高度了
如果两个石柱两两可以到达,那么在A的出点向B的入点建一条边,其容量为INF,来模拟蜥蜴跳过去的过程
虚拟两个点,一个为源点s,一个为汇点t,如果石柱上有蜥蜴的话,从s到石柱的入点连一条边,容量为1,表示跳过一只蜥蜴
如果蜥蜴在这个石柱上可以跳出地图,那么从石柱的出点向t连一条边容量为INF,模拟蜥蜴跳的过程
这样的话跑从s到t的最大流就是蜥蜴逃出的最大数了,再用蜥蜴的总数一减就是答案了
我用的是EK,懒得改Dinci,用的矩阵,反正图小
AC代码如下

#include <cstdio>#include <iostream>#include <queue>  #include <cstring>using namespace std;const int INF=0x7fffffff;int n,m,d;char high[1001][1001];int map[1010][1010];int cnt;int ans;int in[1001][1001];int flow[10001];int pre[10001];queue<int> dl;void make_map(int x,int y)  {    int now=in[x][y]+1;    for (int i=1;i<=n;i++)      for (int j=1;j<=m;j++)        if((i!=x||j!=y)&&(high[i][j]>'0'))        {          if (d*d>=(x-i)*(x-i)+(y-j)*(y-j))            map[now][in[i][j]]=INF;        }  }void go(){    for (int i=1;i<=n;i++)       for (int j=1;j<=m;j++)        if (i-d<1||i+d>n||j-d<1||j+d>m)        {          int dd=in[i][j]+1;          map[dd][cnt]=INF;        }  }int BFS(int s,int t){    while(!dl.empty())     dl.pop();    memset(pre,-1,sizeof(pre));    pre[s]=0;    flow[s]=INF;    dl.push(s);    while(!dl.empty())    {        int dd=dl.front();        dl.pop();        if(dd==t)         break;        for(int i=1;i<=cnt;i++)         if(map[dd][i]>0&&pre[i]==-1)          {            pre[i]=dd;            flow[i]=min(flow[dd],map[dd][i]);            dl.push(i);          }    }    if(pre[t]==-1)     return -1;    else      return flow[t];}int max_flow(int s,int t){    int mflow=0;    int d=0;    while((d=BFS(s,t))!=-1)    {        int k=t;        while(k!=s)         {            map[pre[k]][k]-=d;            map[k][pre[k]]+=d;            k=pre[k];         }         mflow+=d;    }    return mflow;}int main(){    scanf("%d%d%d",&n,&m,&d);    for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++)      {        cin>>high[i][j];        if(high[i][j]!='0')         {            in[i][j]=++cnt;            map[cnt][++cnt]=high[i][j]-'0';         }      }     for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++)      {        char c;        cin>>c;        if(c=='L') ans++,map[0][in[i][j]]=1;        if(high[i][j]>'0') make_map(i,j);      }    cnt++;    go();    printf("%d",ans-max_flow(0,cnt));    return 0;}
1 0
原创粉丝点击