最大流Dinic算法

嘿嘿嘿,时隔不久又见到了DInic,再次回顾一下吧

 不过这次我倒是不想深究,而是想多做一些题,因为这几次比赛下来,算法不是重点,重点是题目如何转化,算法如何应用,这也是比赛为什么让你带着板子的原因吧,所以算法基本思想掌握了就好,不要去背,一看就能想通就行

Dinic算法通过bfs优先的分层处理,加以当前弧的优化,使得dfs寻找 最大流的更多,不像ff算法dfs效率低下,通过分层使得dfs明确了寻找方向,当前弧的优化,使得dfs寻边效率大大提高

Code

一些基本操作

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#define inf (1 << 28)
using namespace std;
typedef long long ll;
const int maxn = 220;
const int maxm = 4e4 + 4e2;
int n,m;
struct node{
    int pre;
    int to,cost;
}e[maxm];
int id[maxn],cnt;
//层数 int flor[maxn]; int cur[maxn];//DFS的优化遍历::当前弧优化 void add(int from,int to,int cost) { e[cnt].to = to; e[cnt].cost = cost; e[cnt].pre = id[from]; id[from] = cnt++; swap(from,to); e[cnt].to = to; e[cnt].cost = 0; e[cnt].pre = id[from]; id[from] = cnt++; }

 bfs分层处理

其实明白了思路,这个很简单就能写出来

int bfs(int s,int t)
{
    memset(flor,0,sizeof(flor));
    queue < int > q;
        while(q.size())q.pop();
    flor[s] = 1;
    q.push(s);

    while(q.size())
    {
        int now = q.front();
        q.pop();
        for(int i = id[now];~i;i=e[i].pre)
        {
            int to = e[i].to;
            int cost = e[i].cost;
            if(flor[to] == 0 && cost > 0)
            {
                flor[to] = flor[now] + 1;
                q.push(to);
                if(to == t)return 1;
            }
        }
    }
    return 0;
}

 dfs当前弧度的优化

dfs比较难懂,为什么要懂ff就是因为一切的算法都是以简单算法为基础的优化过来的

value:是s - s’的最大流(起始点为s)

ret:s' - t的残流(起始点为s’)

一层一层的递归,value - ret就是最大流了,具体还是理解代码展现出的思想

记得我第一次看的时候,dinic真的好绝望...看了n多篇博客,最后也没有

int dfs(int s,int t,int value)
{
    //ret表示目前流到s的最大流量,用来计算回溯的时候是否还有可行流
    int ret = value;
    if(s == t || value == 0)return value;

    int a;

    for(int &i = cur[s];~i;i = e[i].pre)
    {
        int to = e[i].to;
        int cost = e[i].cost;
        if(flor[to] == flor[s] + 1 && (a = dfs(to,t,min(ret,cost))))
        {
            e[i].cost -= a;
            e[i^1].cost += a;
            ret -= a;
            if(ret == 0)break;
        }
    }
    //s点后面没有可行的流了,flor[s] = 0就表示废掉了这个点
    if(ret == value) flor[s] = 0;
    return value - ret;
}

 DInic算法就是基于bfs来dfs的

int dinic(int s,int t)
{
    ll ret = 0;
    while(bfs(s,t))
    {
        memcpy(cur,id,sizeof(id));
        ret += dfs(s,t,inf);
    }
    return ret;
}

 其他的就简单啦

void init()
{
    memset(id,-1,sizeof(id));
    cnt = 0;
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        init();
        int a,b,x;
        for(int i = 1;i <= m;++i)
        {
            scanf("%d%d%d",&a,&b,&x);
            add(a,b,x);
        }
        ll ret = dinic(1,n);
        printf("%lld\n",ret);
    }
    return 0;
}
posted @ 2018-09-20 19:51  Butterflier  阅读(218)  评论(0编辑  收藏  举报