• BZOJ 1001 狼抓兔子 (网络流最小割/平面图的对偶图的最短路)


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001

    算法讨论:

    1、可以用最大流做,最大流等于最小割。

    2、可以把这个图转化其对偶图,然后在对偶图上跑最短路即可。

    一个平面图的最小割等价于其对偶图从S到T的最短路。并不是所有的图都有对偶图,平面图也有一定的要求,自己可以百度一下。

    代码(用BZOJ的数据测过了,但是在BZOJ上过不去。爆WA,并不知道是为什么,里面有个特判,并不知道有没有用处。)

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <cstdio>
      6 
      7 using namespace std;
      8 
      9 const int N = 2000000 + 5;
     10 const int inf = 0x3f3f3f3f;
     11 
     12 int n, cnt, m;
     13 int head[N], que[N], dis[N];
     14 bool vis[N];
     15 
     16 struct Edge {
     17   int from, to, dis, next;
     18 }edges[N * 4];
     19 
     20 void add(int u, int v, int dis) {
     21   ++ cnt;
     22   edges[cnt].from = u; edges[cnt].to = v;
     23   edges[cnt].dis = dis; edges[cnt].next = head[u];
     24   head[u] = cnt;
     25   ++ cnt;
     26   edges[cnt].from = v; edges[cnt].to = u;
     27   edges[cnt].dis = dis; edges[cnt].next = head[v];
     28   head[v] = cnt;
     29 }
     30 
     31 void spfa(int s, int t) {
     32   int h = 1, tail = 1;
     33   for(int i = s; i <= t; ++ i) {
     34     dis[i] = inf;
     35     vis[i] = false;
     36   }
     37   vis[s] = true; dis[s] = 0;
     38   que[h] = s;
     39   while(h <= tail) {
     40     int x = que[h];
     41     vis[x] = false;
     42     for(int i = head[x]; i; i = edges[i].next) {
     43       int v = edges[i].to;
     44       if(dis[v] > dis[x] + edges[i].dis) {
     45         dis[v] = dis[x] + edges[i].dis;
     46         if(!vis[v]) {
     47           que[++ tail] = v;
     48           vis[v] = true;
     49         }
     50       }
     51     }
     52     ++ h;
     53   }
     54   printf("%d
    ", dis[t]);
     55 }
     56 
     57 #define stone
     58 
     59 int main() {
     60 #ifndef stone
     61 
     62   freopen("bjrabbit.in", "r", stdin);
     63   freopen("bjrabbit.out", "w", stdout);
     64 
     65 #endif
     66   
     67   int tmp, s, t, x, mn = 0x3f3f3f3f;
     68   scanf("%d%d", &n, &m);
     69   s = 0; t = (n - 1) * (m - 1) * 2 + 1;
     70   tmp = (m - 1) * 2;
     71   for(int i = 1; i <= n; ++ i) {
     72     for(int j = 1; j < m; ++ j) {
     73       scanf("%d", &x);
     74       mn = min(x, mn);
     75       if(i == 1) {
     76         add(j * 2 + tmp * (i - 1), t, x);
     77       }
     78       else if(i == n) {
     79         add(s, j * 2 + tmp * (i - 2) - 1, x);
     80       }
     81       else {
     82         add(j * 2 + tmp * (i - 1), j * 2 + tmp * (i - 2) - 1, x);
     83       }
     84     }
     85   }
     86   for(int i = 1; i < n; ++ i) {
     87     for(int j = 1; j <= m; ++ j) {
     88       scanf("%d", &x);
     89       mn = min(x, mn);
     90       if(j == 1) {
     91         add(s, tmp * (i - 1) + 1, x);
     92       }
     93       else if(j == m) {
     94         add(tmp * i, t, x);
     95       }
     96       else {
     97         add(tmp * (i - 1) + 2 * (j - 1), tmp * (i - 1) + 2 * (j - 1) + 1, x);
     98       }
     99     }
    100   }
    101   for(int i = 1; i < n; ++ i) {
    102     for(int j = 1; j < m; ++ j) {
    103       scanf("%d", &x);
    104       mn = min(mn, x);
    105       add(tmp * (i - 1) + j * 2, tmp * (i - 1) + j * 2 - 1, x);
    106     }
    107   }
    108   if(n == 1 || m == 1) printf("%d
    ", mn);
    109   else spfa(s, t);
    110 
    111 #ifndef stone
    112 
    113   fclose(stdin); fclose(stdout);
    114 
    115 #endif
    116   
    117   return 0;
    118 }
    1001
  • 相关阅读:
    字符串的输入函数gets
    51nod 1113(矩阵快速幂简单题)
    矩阵快速幂基础
    hdu-2141(二分查找+暴力)
    opencv 摄像头 指定大小 数量 的图片
    Windows环境下使用tensorflow opencv的小事儿
    Vue+D3 V4 实现模块化
    Vue安装
    js 日历
    js基础
  • 原文地址:https://www.cnblogs.com/sxprovence/p/5308056.html
Copyright © 2020-2023  润新知