• bzoj1066: [SCOI2007]蜥蜴


    1066: [SCOI2007]蜥蜴

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 3288  Solved: 1639
    [Submit][Status][Discuss]

    Description

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

    Input

      输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
    ,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

    Output

      输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

    Sample Input

    5 8 2
    00000000
    02000000
    00321100
    02000000
    00000000
    ........
    ........
    ..LLLL..
    ........
    ........

    Sample Output

    1

    HINT

    100%的数据满足:1<=r, c<=20, 1<=d<=4

    Source

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define inf 0x7fffffff
      5 using namespace std;
      6 struct data{int to,next,v;}e[500001];
      7 int r,c,d,cnt=1,ans,mp[21][21],mark[21][21],q[802],h[802],head[802];
      8 void ins(int u,int v,int w)
      9 {cnt++;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].v=w;}
     10 void insert(int u,int v,int w)
     11 {ins(u,v,w);ins(v,u,0);}
     12 bool judge(int x1,int y1,int x2,int y2)
     13 {
     14     if(((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))<=(d*d)&&mp[x1][y1]&&mp[x2][y2])return 1;
     15     return 0;
     16 }
     17 void build()
     18 {
     19      for(int x1=1;x1<=r;x1++)
     20         for(int y1=1;y1<=c;y1++)
     21            for(int x2=x1-d;x2<=x1+d;x2++)
     22               for(int y2=y1-d;y2<=y1+d;y2++)
     23      if(judge(x1,y1,x2,y2)&&(x1!=x2||y1!=y2))insert(mark[x1][y1]+400,mark[x2][y2],inf); 
     24      for(int i=1;i<=r;i++)
     25         for(int j=1;j<=c;j++)
     26            if(mp[i][j])insert(mark[i][j],mark[i][j]+400,mp[i][j]);
     27  } 
     28 bool bfs()
     29 {
     30      memset(h,-1,sizeof(h));
     31      int t=0,w=1,i,now;q[0]=h[0]=0;
     32      while(t<w)
     33      {
     34                now=q[t];t++;i=head[now];
     35                while(i)
     36                {
     37                        if(e[i].v&&h[e[i].to]==-1)
     38                        {
     39                            h[e[i].to]=h[now]+1;
     40                            q[w++]=e[i].to; 
     41                            }
     42                        i=e[i].next; 
     43                        }
     44                }
     45      if(h[801]==-1)return 0;return 1;
     46  }
     47 int dfs(int x,int f)
     48 {
     49     if(x==801)return f;
     50     int i=head[x],used=0,w;
     51     while(i)
     52     {
     53             if(e[i].v&&h[e[i].to]==h[x]+1)
     54             {
     55                 w=f-used;w=dfs(e[i].to,min(w,e[i].v));
     56                 e[i].v-=w;e[i^1].v+=w;
     57                 used+=w;if(used==f)return f;
     58                                           }
     59             i=e[i].next;
     60             }
     61     if(!used)h[x]=-1;
     62     return used;
     63 }
     64 void dinic(){while(bfs())ans-=dfs(0,inf);}
     65 int main()
     66 {
     67     scanf("%d%d%d",&r,&c,&d);
     68     char ch[21];
     69     for(int i=1;i<=r;i++)
     70     {
     71        scanf("%s",ch);
     72        for(int j=1;j<=c;j++)
     73            mp[i][j]=ch[j-1]-'0';
     74           }
     75     int tot=0;
     76     for(int i=1;i<=r;i++)
     77        for(int j=1;j<=c;j++)
     78        {tot++;mark[i][j]=tot;} 
     79     for(int i=1;i<=r;i++)
     80     {
     81        scanf("%s",ch);
     82        for(int j=1;j<=c;j++)
     83            if(ch[j-1]=='L')
     84              {insert(0,mark[i][j],1);ans++;}
     85           }
     86     for(int i=1;i<=d;i++)
     87        for(int j=d+1;j<=r-d;j++)
     88        {
     89           insert(mark[j][i]+400,801,inf);
     90           insert(mark[j][c-i+1]+400,801,inf);
     91           }
     92     for(int i=1;i<=d;i++)
     93        for(int j=1;j<=c;j++)
     94        {
     95           insert(mark[i][j]+400,801,inf);
     96           insert(mark[r-i+1][j]+400,801,inf);
     97           }
     98     build();
     99     dinic();
    100     printf("%d",ans);
    101     return 0;
    102 }
    View Code

    拆点容量为高度(即可以跳高度次)

    没有看到是平面距离一开始被吓到了TAT

    如果有蜥蜴就向入点连个边 容量为1

    可达到的点连边容量为inf

    如果可以跳出去就向T连边容量为inf

  • 相关阅读:
    还在使用golang 的map 做Json编码么?
    Golang 性能测试(2) 性能分析
    golang 性能测试 (1) 基准性能测试
    消息队列 NSQ 源码学习笔记 (五)
    消息队列 NSQ 源码学习笔记 (四)
    消息队列 NSQ 源码学习笔记 (三)
    消息队列 NSQ 源码学习笔记 (二)
    消息队列 NSQ 源码学习笔记 (一)
    你不知道的空格
    Supervisor 使用和进阶4 (Event 的使用)
  • 原文地址:https://www.cnblogs.com/Bloodline/p/5885050.html
Copyright © 2020-2023  润新知