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

题意分析

一看就是一道网络流的题目,然后上去最大流直接搞。
然后发现超时了,所以学了一波当前弧优化,然后就过了。
然后我觉得还可以再快一点,就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
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭