zoukankan      html  css  js  c++  java
  • BZOJ1001: [BeiJing2006]狼抓兔子

    1001: [BeiJing2006]狼抓兔子

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 25579  Solved: 6490
    [Submit][Status][Discuss]

    Description

    现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
    而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:

     

    左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 
    1:(x,y)<==>(x+1,y) 
    2:(x,y)<==>(x,y+1) 
    3:(x,y)<==>(x+1,y+1) 
    道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,
    开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击
    这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,
    才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
    狼的数量要最小。因为狼还要去找喜羊羊麻烦.

    Input

    第一行为N,M.表示网格的大小,N,M均小于等于1000.
    接下来分三部分
    第一部分共N行,每行M-1个数,表示横向道路的权值. 
    第二部分共N-1行,每行M个数,表示纵向道路的权值. 
    第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 
    输入文件保证不超过10M

    Output

    输出一个整数,表示参与伏击的狼的最小数量.

    Sample Input

    3 4
    5 6 4
    4 3 1
    7 5 3
    5 6 7 8
    8 7 6 5
    5 5 5
    6 6 6

    Sample Output

    14

    HINT

     2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

    Source

    【题解】

    听说dinic能过的,看到“ 2015.4.16新加数据一组,可能会卡掉从前可以过的程序。”立马删掉写好的dinic

    平面图最小割 = 对偶图最短路

    https://wenku.baidu.com/view/5a7df375a417866fb84a8e54.html

    挺不错的

    注意细节。。。

    n = 1/m = 1的时候,会有一个边界的边没有建上去

    需要特判

    或者改一下读入时的if else,改成if也行 大概

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #define min(a, b) ((a) < (b) ? (a) : (b))
      9 #define max(a, b) ((a) > (b) ? (a) : (b))
     10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     11 inline void swap(int &a, int &b)
     12 {
     13     int tmp = a;a = b;b = tmp;
     14 }
     15 inline void read(int &x)
     16 {
     17     x = 0;char ch = getchar(), c = ch;
     18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     20     if(c == '-') x = -x;
     21 }
     22 
     23 const int INF = 0x3f3f3f3f;
     24 const int MAXN = 2100000;
     25 const int MAXM = 7100000;
     26 
     27 struct Edge
     28 {
     29     int v,w,nxt;
     30     Edge(int _v, int _w, int _nxt){v = _v;w = _w;nxt = _nxt;}
     31     Edge(){}
     32 }edge[MAXM];
     33 int head[MAXN + 100], cnt = 1, S = MAXN + 1, T = MAXN + 2;
     34 
     35 inline void insert(int a, int b, int c)
     36 {
     37     edge[++cnt] = Edge(b,c,head[a]);
     38     head[a] = cnt;
     39     edge[++cnt] = Edge(a,c,head[b]);
     40     head[b] = cnt;
     41 }
     42 int n,m;
     43 
     44 int d[MAXN + 100], b[MAXN + 100];
     45 
     46 struct Node
     47 {
     48     int u,w;
     49     Node(int _u, int _w){u = _u;w = _w;}
     50     Node(){}
     51 };
     52 
     53 struct cmp
     54 {
     55     bool operator()(Node a, Node b)
     56     {
     57         return a.w > b.w;
     58     }
     59 };
     60 
     61 std::priority_queue<Node, std::vector<Node>, cmp> q;
     62 
     63 void dij()
     64 {
     65     memset(d, 0x3f, sizeof(d));
     66     d[S] = 0;
     67     q.push(Node(S, 0));
     68     while(q.size())
     69     {
     70         Node now = q.top();q.pop();
     71         if(b[now.u]) continue;
     72         b[now.u] = 1;
     73         for(int pos = head[now.u];pos != -1;pos = edge[pos].nxt)
     74         {
     75             int v = edge[pos].v;
     76             if(d[v] > d[now.u] + edge[pos].w)
     77             {
     78                 d[v] = d[now.u] + edge[pos].w;
     79                 q.push(Node(v, d[v]));
     80             }
     81         }
     82     }
     83 }
     84 
     85 int main()
     86 {
     87     memset(head, -1, sizeof(head));
     88     read(n), read(m);
     89     if(n == 1)
     90     {
     91         int ans = INF;
     92         for(register int i = 1;i < m;++ i)
     93         {
     94             int tmp;read(tmp);
     95             ans = min(ans, tmp);
     96         }
     97         printf("%d", ans);
     98         return 0;
     99     }
    100     else if(m == 1)
    101     {
    102         int ans = INF;
    103         for(register int i = 1;i < n;++ i)
    104         {
    105             int tmp;read(tmp);
    106             ans = min(ans, tmp);
    107         }
    108         printf("%d", ans);
    109         return 0;
    110     }
    111     for(register int i = 0;i < n;++ i)
    112         for(register int j = 0;j < m - 1;++ j)
    113         {
    114             int tmp;read(tmp);
    115             if(i == 0) insert(S, (i * m + j) << 1, tmp);
    116             else if(i == n - 1) insert(T, ((i - 1) * m + j) << 1 | 1, tmp);
    117             else insert((i * m + j) << 1, ((i - 1) * m + j) << 1 | 1, tmp);
    118         }
    119     for(register int i = 0;i < n - 1;++ i)
    120         for(register int j = 0;j < m;++ j)
    121         {
    122             int tmp;read(tmp);
    123             if(j == 0) insert(T, (i * m + j) << 1 | 1, tmp);
    124             else if(j == m - 1) insert(S, (i * m + j - 1) << 1, tmp);
    125             else insert((i * m + j) << 1 | 1, (i * m + j - 1) << 1 ,tmp);
    126         }
    127     for(register int i = 0;i < n - 1;++ i)
    128         for(register int j = 0;j < m - 1;++ j)
    129         {
    130             int tmp;read(tmp);
    131             insert((i * m + j) << 1, (i * m + j) << 1 | 1, tmp);
    132         }
    133     dij();
    134     printf("%d", d[T]);
    135     return 0;
    136 } 
    BZOJ1001
  • 相关阅读:
    在循环中正确找到对应DOM元素的索引
    JavaScript继承方式(1)
    JavaScript的写类方式(1)
    基于WF4的新平台地理模块的3D模块
    基于WF4的新平台流程模式(4)动态并发
    基于WF4的新平台流程模式(9)表单路由启动传入
    基于WF4的新平台地理模块的3D模块
    基于WF4的新平台流程模式(2)启动条件路由
    基于WF4的新平台表单设计器功能简介
    我的2010年
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8001689.html
Copyright © 2011-2022 走看看