BZOJ1001 [BeiJing2006]狼抓兔子 (网络流)

原创 2018年04月17日 18:30:13

题意分析

一看就是一道网络流的题目,然后上去最大流直接搞。
然后发现超时了,所以学了一波当前弧优化,然后就过了。
然后我觉得还可以再快一点,就IO加速了一下, 发现速度提高了400ms。
嗯,FASTIO还是很强的。
还有这道题是无向图,所以正反边容量都是w,一开始我建成正边w反边0,过不了。原因是有向图和无向图还是不一样的,会影响到增广的情况。
另外因为是平面图,所以可以求出对偶图,然后用最短路来求最小割。
我懒所以就不想学了。

代码总览

#include<bits/stdc++.h>
#define FI(n) FastIO::read(n)
using namespace std;
const int nmax = 1e6+10;
typedef struct{
    int to,nxt,w;
}Edge;
Edge e[nmax*6];
int head[nmax], dep[nmax];
int cur[nmax];
int tot = 0;
int n,m;
namespace FastIO {
    const int SIZE = 1 << 16;
    char buf[SIZE], obuf[SIZE], str[60];
    int bi = SIZE, bn = SIZE, opt;
    int read(char *s) {
        while (bn) {
            for (; bi < bn && buf[bi] <= ' '; bi++);
            if (bi < bn) break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        int sn = 0;
        while (bn) {
            for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
            if (bi < bn) break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        s[sn] = 0;
        return sn;
    }
    bool read(int& x) {
        int n = read(str), bf;
        if (!n) return 0;
        int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
        for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
        if (bf < 0) x = -x;
        return 1;
    }
};
void add(int u, int v, int w){
    e[tot].to = v;
    e[tot].nxt = head[u];
    e[tot].w = w;
    head[u]=tot++;
}
bool bfs(){
    queue<int> q;
    memset(dep,0,sizeof dep); dep[1] = 1; q.push(1);
    while(!q.empty()){
        int u = q.front(); q.pop();
        for(int i = head[u]; i!=-1;i = e[i].nxt){
            int v = e[i].to;
            if(e[i].w > 0 && dep[v] == 0){
                dep[v] = dep[u] +1;
                q.push(v);
            }
        }
    }
    return dep[n*m] != 0;
}
int dfs(int u, int dis){
    if(u == n*m || dis == 0) return dis;
    for(int & i = cur[u];i!=-1;i=e[i].nxt){
        int v = e[i].to, w = e[i].w;
        if(dep[v] == dep[u] +1 && w > 0){
            int tt = dfs(v,min(dis,w));
            if(tt > 0){
                e[i].w -= tt;
                e[i^1].w += tt;
                return tt;
            }
        }
    }
    return 0;
}
int Dinic(){
    int ans = 0;
    while(bfs()){
        for(int i = 1;i<=n*m;++i) cur[i] = head[i];
        while(int t = dfs(1,0x3f3f3f3f))
            ans += t;
    }
    return ans;
}
int main(){
    memset(head,-1,sizeof head);
    FI(n);FI(m);
    int w;
    for(int i = 0;i<n;++i){
        for(int j = 1;j<m;++j){
            FI(w);
            add(i*m+j,i*m+j+1,w);
            add(i*m+j+1,i*m+j,w);
        }
    }
    for(int i = 1;i<=n-1;++i){
        for(int j = 1;j<=m;++j){
            FI(w);
            add((i-1)*m+j,i*m+j,w);
            add(i*m+j,(i-1)*m+j,w);
        }
    }
    for(int i = 1;i<=n-1;++i){
        for(int j = 1;j<=m-1;++j){
            FI(w);
            add((i-1)*m+j,i*m+j+1,w);
            add(i*m+j+1,(i-1)*m+j,w);

        }
    }
    printf("%d\n",Dinic());
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pengwill97/article/details/79978862

bzoj1001【BeiJing2006】狼抓兔子

平面图转对偶图+dijkstra+优先队列
  • AaronGZK
  • AaronGZK
  • 2015-07-26 12:51:16
  • 834

BZOJ1001 [Beijing2006] 狼抓兔子

相关资料: 浅析最大最小定理在信息学竞赛中的应用 北京大学ACM暑期课讲义-网络流 根据最大流-最小割定理,一个网络中,两个边缘点之间的最大流等于最小割(最小割就是用一条割线将两个点分割在两个图中,...
  • whzzt
  • whzzt
  • 2016-02-16 13:44:36
  • 863

BZOJ 1001 [BeiJing2006]狼抓兔子

平面图最小割转对偶图最短路。第一眼看到这题,显然是最小割嘛。。。根据最大流最小割定理,跑一遍最大流即可,但复杂度O(n2∗m)O(n^2*m),显然要T啊。然后我就学习了平面图最小割转对偶图最短路的想...
  • ziqian2000
  • ziqian2000
  • 2016-08-14 15:01:33
  • 362

BZOJ1001: [BeiJing2006]狼抓兔子 (最小割)

传送门 题目大意:求给出图的最小割(……题目就是这个意思)。 明眼一看,这就是一个裸的最大流,可是被数据范围吓住了,有10610^6个点,然后又有3∗1063*10^6条边,对于网络流可怜的O(n...
  • geng4512
  • geng4512
  • 2015-11-15 13:06:04
  • 1677

BZOJ1001: [BeiJing2006]狼抓兔子

BZOJ 1001
  • qazw2424
  • qazw2424
  • 2016-07-23 18:48:18
  • 466

[bzoj1001][BeiJing2006]狼抓兔子

Description给出一张网格,左上角点为(1,1),右下角点为(N,M).有以下三种类型的道路 1:(x,y)(x+1,y) 2:(x,y)(x,y+1) 3:(x,y)(x+1,y...
  • alan_cty
  • alan_cty
  • 2016-06-15 21:07:22
  • 517

【最小割->最短路】BZOJ1001(BeiJing2006)[狼抓兔子]题解

题目概述给出一张网格图,兔子从(1,1)逃向(n,m),有横向道路,纵向道路和对角线道路,每条道路都有一个流量限制(即最多能通过多少兔子),一只狼只能抓一只兔子。问最多在边上放置多少只狼才能完全堵截兔...
  • zzkksunboy
  • zzkksunboy
  • 2017-03-25 21:14:19
  • 319

bzoj 1001: [BeiJing2006]狼抓兔子(s-t平面图求最大流)

题目链接 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 20242  Solved: 5037 [...
  • fouzhe
  • fouzhe
  • 2017-01-22 10:50:10
  • 325

BZOJ1001 [BeiJing2006]狼抓兔子(网络流最小割)

题目可以转化为:选出一个边集,使得去掉它之后,(1,1)与(n,m)不通  即:以(1,1)为源,(n,m)为汇,求该图最小割  不过由于节点过多,直接对输入的图求最小割的话会超时  转化:求它的对...
  • cjk_cjk
  • cjk_cjk
  • 2015-01-05 01:45:22
  • 990

BZOJ 1001([BeiJing2006]狼抓兔子-最大流转对偶图最短路)

1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 5779  Solved: 1297 [Subm...
  • nike0good
  • nike0good
  • 2013-04-21 09:37:22
  • 2565
收藏助手
不良信息举报
您举报文章:BZOJ1001 [BeiJing2006]狼抓兔子 (网络流)
举报原因:
原因补充:

(最多只允许输入30个字)