• bzoj 1001 [BeiJing2006]狼抓兔子


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

    最小割转化最短路的经典题目。

    题目看起来是求最小割,看一下割和最小割的定义:

    割: 对一个图,把所有顶点分成两个集合 S 和 T=V-S ,其中源点 s 在集合 S 中,汇点 t 在集合 T 中。如果把 “起点在 S 中,终点在 T 中” 的边全部删除,就无法从 s 到达 t 了。这样的集合划分 (S,T)称为一个 s-t 割,它的容量为起点在 S 中,终点在 T 中的所有边的容量和。

    最小割: 图中容量最小的割。

    由最小割最大流定理:

        For any network having a single origin and single destination node, the maximum possible flow from origin to destination equals the minimum cut value for all cuts in the network.

    那么跑一遍最大流就出来了?但是V,E都能达到1e3,我所知的最快网络流算法ISAP都要O(V^2 E),所以网络流不可行。

    题目中这样的图被称为s-t平面图,这样的图作它的对偶图求最短路。

    具体看周冬的《两极相通——浅析最大最小定理在信息学竞赛中的应用》

      1 /*
      2  * Problem:  bzoj 1001
      3  * Author:  SHJWUDP
      4  * Created Time:  2015/3/26 星期四 16:36:42
      5  * File Name: 233.cpp
      6  * State: Accepted
      7  * Memo: 网络流->最短路
      8  */
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <queue>
     14  
     15 using namespace std;
     16  
     17 const int INF=0x7f7f7f7f;
     18  
     19 const int MaxA=1e3+7;
     20 const int MaxB=MaxA*MaxA*2;
     21 const int MaxC=MaxA*MaxA*3;
     22  
     23 struct Edge {
     24     int v, nt;
     25     int w;
     26 } edges[MaxC];
     27  
     28 int head[MaxB], edgeNum;
     29  
     30 int N, M;
     31 int s, t;
     32  
     33 void init(int n) {
     34     memset(head, -1, sizeof(head[0])*(n+3));
     35     edgeNum=0;
     36 }
     37 void addEdge(int u, int v, int w) {
     38     edges[edgeNum].v=v;
     39     edges[edgeNum].w=w;
     40     edges[edgeNum].nt=head[u];
     41     head[u]=edgeNum++;
     42 }
     43 namespace Dijkstra {
     44     struct HeapNode {
     45         int d, u;
     46         HeapNode(int d, int u):d(d), u(u) {}
     47         bool operator<(const HeapNode& rhs) const {
     48             return d > rhs.d;
     49         }
     50     };
     51  
     52     int n;
     53     int d[MaxA*MaxA<<1];
     54     bool done[MaxA*MaxA<<1];
     55     int go(int s) {
     56         memset(d, 0x7f, sizeof(d[0])*(n+3));
     57         memset(done, 0, sizeof(done[0])*(n+3));
     58         d[s]=0; done[s]=1;
     59         priority_queue<HeapNode> Q;
     60         Q.push(HeapNode(0, s));
     61         while(!Q.empty()) {
     62             HeapNode x=Q.top(); Q.pop();
     63             for(int i=head[x.u]; ~i; i=edges[i].nt) {
     64                 Edge& e=edges[i];
     65                 if(d[e.v]>d[x.u]+e.w) {
     66                     d[e.v]=d[x.u]+e.w;
     67                     if(!done[e.v]) {
     68                         done[e.v]=1;
     69                         Q.push(HeapNode(d[e.v], e.v));
     70                     }
     71                 }
     72             }
     73         }
     74         return d[t]>=INF?0:d[t];
     75     }
     76 }
     77 int main() {
     78 #ifndef ONLINE_JUDGE
     79     freopen("in", "r", stdin);
     80     //freopen("out", "w", stdout);
     81 #endif
     82     while(~scanf("%d%d", &N, &M)) {
     83         s=(N-1)*(M-1)*2+1; t=(N-1)*(M-1)*2+2;
     84         init(Dijkstra::n=(N-1)*(M-1)*2+2);
     85         int x;
     86         for(int i=0; i<N; i++)
     87             for(int j=0; j<M-1; j++) {
     88                 scanf("%d", &x);
     89                 addEdge(i==0?s:((i-1)*(M-1)+j)<<1|1, i==N-1?t:(i*(M-1)+j)<<1, x);
     90             }
     91         for(int i=0; i<N-1; i++)
     92             for(int j=0; j<M; j++) {
     93                 scanf("%d", &x);
     94                 addEdge(j==M-1?s:(i*(M-1)+j)<<1|1, j==0?t:(i*(M-1)+(j-1))<<1, x);
     95             }
     96         for(int i=0; i<N-1; i++)
     97             for(int j=0; j<M-1; j++) {
     98                 scanf("%d", &x);
     99                 addEdge((i*(M-1)+j)<<1, (i*(M-1)+j)<<1|1, x);
    100             }
    101          
    102         printf("%d
    ", Dijkstra::go(s));
    103     }
    104     return 0;
    105 }
    bzoj 1001
  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/shjwudp/p/4386827.html
Copyright © 2020-2023  润新知