码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-07-12 09:33:50      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

题意很明显就是求最小割了,根据最小割最大流定理,数值等价于求最大流。

上模板。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1000010;//点数的最大值
const int MAXM = 6000060;//边数的最大值
const int INF = 0x3f3f3f3f;
struct Dinic
{
    int n, m, T, e, first[MAXN], next[MAXM], u[MAXM], v[MAXM], flow[MAXM];
    int q[MAXN], d[MAXN], work[MAXN], s[MAXN];
    void add(int a, int b, int f)
    {
        u[e] = a;
        v[e] = b;
        flow[e] = f;
        next[e] = first[a];
        first[a] = e;
        e ++;
    }
    void init(int n,int m)
    {
        this->n=n;
        this->m=m;
        T = n * m - 1;
        e = 0;
        for(i = 0; i <= T; i ++)
            first[i] = -1;
    }
    int bfs()
    {
        int i, j, rear;
        for(i = 1; i <= T; i ++)
            d[i] = -1;
        d[0] = 0;
        rear = 0;
        q[rear ++] = 0;
        for(i = 0; i < rear ; i ++)
            for(j = first[q[i]]; j != -1; j = next[j])
                if(flow[j] && d[v[j]] == -1)
                {
                    d[v[j]] = d[q[i]] + 1;
                    if(v[j] == T)
                        return 1;
                    q[rear ++] = v[j];
                }
        return 0;
    }
    int dinic()
    {
        int i, j, cur, r, res = 0;
        while(bfs())
        {
            r = 0;
            cur = 0;
            for(i = 0; i <= T; i ++)
                work[i] = first[i];
            for(;;)
            {
                if(cur == T)
                {
                    int a = INF, minr = r;
                    for(i = 0; i < r; i ++)
                        if(flow[s[i]] < a)
                        {
                            a = flow[s[i]];
                            minr = i;
                        }
                    for(i = 0; i < r; i ++)
                    {
                        flow[s[i]] -= a;
                        flow[s[i] ^ 1] += a;
                    }
                    r = minr;
                    cur = u[s[r]];
                    res += a;
                }
                for(i = work[cur]; i != -1; i = next[i])
                    if(flow[i] && d[v[i]] == d[cur] + 1)
                        break;
                work[cur] = i;
                if(i != -1)
                {
                    s[r ++] = i;
                    cur = v[i];
                }
                else
                {
                    d[cur] = -1;
                    if(r == 0)
                        break;
                    r --;
                    cur = u[s[r]];
                }
            }
        }
        return res;
    }
};
Dinic dinic;
int main()
{
    int n,m;
    while(scanf("%d%d", &n, &m) == 2)
    {
        dinic.init(n,m);
        int x;
            for(int i=0; i<n; ++i)
            {
                for(int j=0; j<m-1; ++j)
                {
                    scanf("%d",&x);
                    dinic.add(i*m+j,i*m+j+1,x);
                    dinic.add(i*m+j+1,i*m+j,x);
                }
            }
            for(int i=0; i<n-1; ++i)
            {
                for(int j=0; j<m; ++j)
                {
                    scanf("%d",&x);
                    dinic.add(i*m+j,(i+1)*m+j,x);
                    dinic.add((i+1)*m+j,i*m+j,x);
                }
            }
            for(int i=0; i<n-1; ++i)
            {
                for(int j=0; j<m-1; ++j)
                {
                    scanf("%d",&x);
                    dinic.add(i*m+j,(i+1)*m+j+1,x);
                    dinic.add((i+1)*m+j+1,i*m+j,x);
                }
            }
        printf("%d\n", dinic.dinic());
    }
    return 0;
}
View Code

 

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

标签:

原文地址:http://www.cnblogs.com/rockzh/p/4640489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!