• BZOJ 1066 蜥蜴 最大流


    题目链接:

    https://www.lydsy.com/JudgeOnline/problem.php?id=1066

    题目大意:

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

    思路:

    网络流拆点建图。

    对于每个石柱进行拆成两个点,然后在这两个点中限制最大流为石柱高度,这样保证经过石柱的次数,对于两个可以互相到达的点从一个点的出点往另一个入点连边,容量为INF,对于可以跳出界的点往汇点连边,对于有蜥蜴的点从源点向其连边。

      1 #include<bits/stdc++.h>
      2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
      3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
      4 #define Min(a, b) ((a) < (b) ? (a) : (b))
      5 #define Mem(a) memset(a, 0, sizeof(a))
      6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
      7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
      8 #define lson ((o)<<1)
      9 #define rson ((o)<<1|1)
     10 #define Accepted 0
     11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
     12 using namespace std;
     13 inline int read()
     14 {
     15     int x=0,f=1;char ch=getchar();
     16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 typedef long long ll;
     21 const int maxn = 1000 + 10;
     22 const int MOD = 1000000007;//const引用更快,宏定义也更快
     23 const int INF = 1e9 + 7;
     24 const double eps = 1e-6;
     25 struct edge
     26 {
     27     int u, v, c, f;
     28     edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){}
     29 };
     30 vector<edge>e;
     31 vector<int>G[maxn];
     32 int level[maxn];//BFS分层,表示每个点的层数
     33 int iter[maxn];//当前弧优化
     34 int m;
     35 void init(int n)
     36 {
     37     for(int i = 0; i <= n; i++)G[i].clear();
     38     e.clear();
     39 }
     40 void addedge(int u, int v, int c)
     41 {
     42     //cout<<u<<" "<<v<<" "<<c<<endl;
     43     e.push_back(edge(u, v, c, 0));
     44     e.push_back(edge(v, u, 0, 0));
     45     m = e.size();
     46     G[u].push_back(m - 2);
     47     G[v].push_back(m - 1);
     48 }
     49 void BFS(int s)//预处理出level数组
     50 //直接BFS到每个点
     51 {
     52     memset(level, -1, sizeof(level));
     53     queue<int>q;
     54     level[s] = 0;
     55     q.push(s);
     56     while(!q.empty())
     57     {
     58         int u = q.front();
     59         q.pop();
     60         for(int v = 0; v < G[u].size(); v++)
     61         {
     62             edge& now = e[G[u][v]];
     63             if(now.c > now.f && level[now.v] < 0)
     64             {
     65                 level[now.v] = level[u] + 1;
     66                 q.push(now.v);
     67             }
     68         }
     69     }
     70 }
     71 int dfs(int u, int t, int f)//DFS寻找增广路
     72 {
     73     if(u == t)return f;//已经到达源点,返回流量f
     74     for(int &v = iter[u]; v < G[u].size(); v++)
     75         //这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历
     76         //在每次找增广路的时候,数组要清空
     77     {
     78         edge &now = e[G[u][v]];
     79         if(now.c - now.f > 0 && level[u] < level[now.v])
     80             //now.c - now.f > 0表示这条路还未满
     81             //level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想
     82         {
     83             int d = dfs(now.v, t, min(f, now.c - now.f));
     84             if(d > 0)
     85             {
     86                 now.f += d;//正向边流量加d
     87                 e[G[u][v] ^ 1].f -= d;
     88     //反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到
     89                 return d;
     90             }
     91         }
     92     }
     93     return 0;
     94 }
     95 int Maxflow(int s, int t)
     96 {
     97     int flow = 0;
     98     for(;;)
     99     {
    100         BFS(s);
    101         if(level[t] < 0)return flow;//残余网络中到达不了t,增广路不存在
    102         memset(iter, 0, sizeof(iter));//清空当前弧数组
    103         int f;//记录增广路的可增加的流量
    104         while((f = dfs(s, t, INF)) > 0)
    105         {
    106             flow += f;
    107         }
    108     }
    109     return flow;
    110 }
    111 struct node
    112 {
    113     int x, y;
    114     node(){}
    115     node(int x, int y):x(x), y(y){}
    116     bool operator < (const node& a)const
    117     {
    118         return x < a.x || x == a.x && y < a.y;
    119     }
    120 };
    121 map<node, int>ID;
    122 char Map[30][30];
    123 int main()
    124 {
    125     int n, m, d;
    126     scanf("%d%d%d", &n, &m, &d);
    127     int tot = 0;
    128     for(int i = 0; i < n; i++)
    129     {
    130         scanf("%s", Map[i]);
    131         for(int j = 0; j < m; j++)
    132         {
    133             if(Map[i][j] != '0')
    134             {
    135                 ID[node(i, j)] = ++tot;
    136                 addedge(tot, tot + 500, Map[i][j] - '0');
    137                 if(i < d || j < d || n - i <= d || m - j <= d)
    138                     addedge(tot + 500, 0, INF);
    139             }
    140         }
    141     }
    142     for(int i = 0; i < n; i++)
    143     {
    144         for(int j = 0; j < m; j++)
    145         {
    146             if(Map[i][j] != '0')
    147             for(int x = -d; x <= d; x++)
    148             {
    149                 for(int y = -d; y <= d; y++)
    150                 {
    151                     int xx = x + i;
    152                     int yy = y + j;
    153                     if(xx >= 0 && xx < n && yy >= 0 && yy < m && (xx != i || yy != j) && Map[xx][yy] != '0')
    154                     {
    155                         if(abs(i - xx) + abs(j - yy) <= d)addedge(ID[node(i, j)] + 500, ID[node(xx, yy)], INF);
    156                     }
    157                 }
    158             }
    159         }
    160     }
    161     int cnt = 0;
    162     for(int i = 0; i < n; i++)
    163     {
    164         scanf("%s", Map[i]);
    165         for(int j = 0; j < m; j++)if(Map[i][j] == 'L')
    166         {
    167             addedge(1000, ID[node(i, j)], 1);
    168             cnt++;
    169         }
    170     }
    171     cout<<cnt-Maxflow(1000, 0)<<endl;
    172     return Accepted;
    173 }
  • 相关阅读:
    学习练习 java输入输出流 练习题1
    学习总结 java Iterator迭代器练习
    学习总结 java 输入输出流
    学习记录 java 哈希
    学习记录 java 链表知识
    学习总结 java 异常
    学习练习 java 集合
    web压缩gzip响应
    web乱码问题
    web附件中文名
  • 原文地址:https://www.cnblogs.com/fzl194/p/9693724.html
Copyright © 2020-2023  润新知