• 1066. [SCOI2007]蜥蜴【最大流】


    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

    辣鸡BZOJ……别的OJ都A了就它A不了…
    一开始看到高度不超过三,以为是什么炒鸡神奇的拆点操作……
    后来想不出来神奇的拆点操作
    就随便把点拆成了一个入点一个出点
    两点间的容量为柱子的高度
    再增设一个超级源点0和各个起点链接,容量为1(1只蜥蜴)
    然后其他的边就全部INF好了……
    瞎搞搞就过了

    UPDATE:改过了……luogu不加优化0ms,BZOJ加了优化还88ms……emmm……

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cmath>
      6 #define MAXM (1000000+10)
      7 #define MAXN (100000+10)
      8 using namespace std;
      9 
     10 struct node
     11 {
     12     int Flow;
     13     int next;
     14     int to;
     15 } edge[MAXM*2];
     16 int Depth[MAXN],q[MAXN];
     17 int head[MAXN],num_edge;
     18 int n,m,s,e,d,INF;
     19 int a[101][101];
     20 char ch;
     21 
     22 void add(int u,int v,int l)
     23 {
     24     edge[++num_edge].to=v;
     25     edge[num_edge].Flow=l;
     26     edge[num_edge].next=head[u];
     27     head[u]=num_edge;
     28 }
     29 
     30 bool Bfs(int s,int e)
     31 {
     32     int Head=0,Tail=1;
     33     memset(Depth,0,sizeof(Depth));
     34     Depth[s]=1;
     35     q[1]=s;
     36     while (Head<Tail)
     37     {
     38         ++Head;
     39         int x=q[Head];
     40         for (int i=head[x]; i!=0; i=edge[i].next)
     41             if (!Depth[edge[i].to] && edge[i].Flow>0)
     42             {
     43                 Depth[edge[i].to]=Depth[x]+1;
     44                 q[++Tail]=edge[i].to;
     45             }
     46     }
     47     if (Depth[e]>0) return true;
     48     return false;
     49 }
     50 
     51 int Dfs(int x,int low)
     52 {
     53     int Min,f=0;
     54     if (x==e || low==0)
     55         return low;
     56     for (int i=head[x]; i!=0; i=edge[i].next)
     57         if (edge[i].Flow>0 && Depth[edge[i].to]==Depth[x]+1 && (Min=Dfs(edge[i].to , min(low,edge[i].Flow) )))
     58         {
     59             edge[i].Flow-=Min;
     60             edge[((i-1)^1)+1].Flow+=Min;
     61             f+=Min;
     62             low-=Min;
     63             if (low==0) break;
     64         }
     65     if (!f) Depth[x]=-1;
     66     return f;
     67 }
     68 
     69 int Dinic(int s,int e)
     70 {
     71     int Ans=0;
     72     while (Bfs(s,e))
     73         Ans+=Dfs(s,0x7fffffff);
     74     return Ans;
     75 }
     76 
     77 int main()
     78 {
     79     s=0,e=520;
     80     int Sum=0;
     81     memset(&INF,0x7f,sizeof(INF));
     82     scanf("%d%d%d",&n,&m,&d);
     83     for (int i=1; i<=n; ++i)
     84         for (int j=1; j<=m; ++j)
     85         {
     86             cin>>ch;
     87             a[i][j]=ch-48;
     88         }
     89     for (int i=1; i<=n; ++i)
     90         for (int j=1; j<=m; ++j)
     91         {
     92             add((i-1)*m+j,(i-1)*m+j+999,a[i][j]);
     93             add((i-1)*m+j+999,(i-1)*m+j,a[i][j]);
     94         }
     95     for (int i=1; i<=n; ++i)
     96         for (int j=1; j<=m; ++j)
     97         {
     98             cin>>ch;
     99             if (ch=='L')
    100             {
    101                 ++Sum;
    102                 add(0,(i-1)*m+j,1);
    103                 add((i-1)*m+j,0,0);
    104             }
    105         }
    106     for (int i=1; i<=n; ++i)
    107         for (int j=1; j<=m; ++j)
    108             if (a[i][j]!=0 && (i<=d || j<=d || m-j<d || n-i<d))
    109             {
    110                 add((i-1)*m+j+999,520,INF);
    111                 add(520,(i-1)*m+j+999,0);
    112             }
    113     for (int i=1; i<=n; ++i)
    114         for (int j=1; j<=m; ++j)
    115             for (int k=1; k<=n; ++k)
    116                 for (int l=1; l<=m; ++l)
    117                     if (!(i==k && j==l) && a[i][j]!=0 && a[k][l]!=0 && sqrt((i-k)*(i-k)+(j-l)*(j-l))<=d)
    118                     {
    119                         add((i-1)*m+j+999,(k-1)*m+l,INF);
    120                         add((k-1)*m+l,(i-1)*m+j+999,0);
    121                     }
    122     printf("%d",Sum-Dinic(0,520));
    123 }
  • 相关阅读:
    应对IBM V7000磁盘故障,你只差这一步!
    鬼知道我经历了什么;记阵列RAID信息丢失的恢复过程
    遇到U盘无法打开,属性显示0字节这样的问题?数据该如何导出?
    2、【Linux网络编程】socket中sockaddr、sockaddr_in和in_addr的区别
    1、【Linux网络编程】socket
    9、wxWidgets 组件wxListBox wxNotebook wxScrolledWindow
    8、wxWidgets 组件wxCheckBox wxBitmapButton wxToggleButton wxStaticLine wxStaticText wxSlider
    7、wxWidgets 对话框
    6、wxWidgets 事件处理
    5、wxWidgets布局管理
  • 原文地址:https://www.cnblogs.com/refun/p/8680747.html
Copyright © 2020-2023  润新知