zoukankan      html  css  js  c++  java
  • 1066: [SCOI2007]蜥蜴

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 4885  Solved: 2525
    [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

    难点在于如何构图,鉴于数据大小,可以暴力构图

    每根柱子分为两个点,从入点跳到出点连一条边,容量为柱子高度

    如果A柱子能跳到B柱子,那么A柱子的出点连一条边到B柱子入点,容量为无限INF

    一个超级源与所有蜥蜴连接,容量为1

    一个超级汇与所有能跳出去的柱子的出点连接,容量为无限INF

    跑一遍最大流,蜥蜴数-最大流就是答案

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cmath>
      7 using namespace std;
      8 
      9 #define sqr(x) ((x)*(x))
     10 
     11 const int INF=0x7fffffff;
     12 
     13 struct data
     14 {
     15     int to,w,next;
     16 }E[500001];
     17 int node=1,ans;
     18 int head[1000],h[1000],q[1000];
     19 int r,c,d;
     20 int mp[30][30],mark[30][30];
     21 
     22 void insert(int u,int v,int w)
     23 {
     24     E[++node]=(data){v,w,head[u]};
     25     head[u]=node;
     26     E[++node]=(data){u,0,head[v]};
     27     head[v]=node;
     28 }
     29 
     30 bool bfs()
     31 {
     32     int i;
     33     memset(h,-1,sizeof(h));
     34     queue<int> Q;
     35     Q.push(0);
     36     h[0]=0;
     37     while(!Q.empty())
     38     {
     39         int p=Q.front();
     40         Q.pop();
     41         i=head[p];
     42         while(i)
     43         {
     44             if(E[i].w&&h[E[i].to]==-1)
     45             {
     46                 Q.push(E[i].to);
     47                 h[E[i].to]=h[p]+1;
     48             }
     49             i=E[i].next;
     50         }
     51     }
     52     if(h[801]==-1) return 0;
     53     return 1;
     54 }
     55 
     56 int dfs(int x,int f)
     57 {
     58     if(x==801) return f;
     59     int i=head[x];
     60     int w,used=0;
     61     while(i)
     62     {
     63         if(E[i].w&&h[E[i].to]==h[x]+1)
     64         {
     65             w=f-used;
     66             w=dfs(E[i].to,min(w,E[i].w));
     67             E[i].w-=w;
     68             E[i^1].w+=w;
     69             used+=w;
     70             if(used==f) return f;
     71         }
     72         i=E[i].next;
     73     }
     74     if(!used) h[x]=-1;
     75     return used;
     76 }
     77 
     78 void dinic()
     79 {
     80     while(bfs()) ans-=dfs(0,INF);
     81 }
     82 
     83 int main()
     84 {
     85     scanf("%d %d %d",&r,&c,&d);
     86     char ch[30];
     87     for(int i=1;i<=r;i++)
     88     {
     89         scanf("%s",ch+1);
     90         for(int j=1;j<=c;j++)
     91             mp[i][j]=ch[j]-'0';
     92     }
     93     int tot=0;
     94     for(int i=1;i<=r;i++)
     95         for(int j=1;j<=c;j++)
     96             mark[i][j]=++tot;
     97     for(int i=1;i<=r;i++)
     98     {
     99         scanf("%s",ch+1);
    100         for(int j=1;j<=c;j++)
    101             if(ch[j]=='L')
    102             {
    103                 ans++;
    104                 insert(0,mark[i][j],1);
    105             }
    106     }
    107     for(int i=1;i<=r;i++)
    108         for(int j=1;j<=c;j++)
    109             if(mp[i][j])
    110             {
    111                 insert(mark[i][j],mark[i][j]+400,mp[i][j]);
    112                 if(i-d<1||i+d>r||j-d<1||j+d>c)
    113                     insert(mark[i][j]+400,801,INF);
    114             }
    115     for(int x1=1;x1<=r;x1++)
    116         for(int y1=1;y1<=c;y1++)
    117             for(int x2=1;x2<=r;x2++)
    118                 for(int y2=1;y2<=c;y2++)
    119                     if((x1!=x2||y1!=y2)&&sqr(x1-x2)+sqr(y1-y2)<=sqr(d)&&mp[x1][y1]&&mp[x2][y2])
    120                         insert(mark[x1][y1]+400,mark[x2][y2],INF);
    121     dinic();
    122     printf("%d
    ",ans);
    123     return 0;
    124 }
  • 相关阅读:
    C51 使用端口 个人笔记
    C51 静态数码管 个人笔记
    C51 矩阵按键 个人笔记
    C51 蜂鸣器 个人笔记
    C51 独立按键 个人笔记
    C51 中断 个人笔记
    CC3200 TI 笔记
    iar修改包含路径的方法
    WCF绑定和行为在普通应用和SilverLight应用一些对比
    用批处理来自动化项目编译及部署(附Demo)
  • 原文地址:https://www.cnblogs.com/InWILL/p/9383716.html
Copyright © 2011-2022 走看看