网络流--最大流

网络流的所有算法都是基于一种增广路的思想,下面首先简要的说一下增广路思想,其基本步骤如下:

1.找到一条从源点到汇点的路径,使得路径上任意一条边的残量>0(注意是大于而不是大于等于,这意味着这条边还可以分配流量),这条路径便称为增广路
2.找到这条路径上最小的F[u][v](我们设F[u][v]表示u->v这条边上的残量即剩余流量),下面记为flow

3.将这条路径上的每一条有向边u->v的残量减去flow,同时对于起反向边v->u的残量加上flow
4.重复上述过程,直到找不出增广路,此时我们就找到了最大流

  最大流板子题,洛谷草地排水。先用bfs求出每个点深度,再用一个类似dfs的东西找到能新走到汇点的权值。多走几次就行了。

       这有一个很棒的博客,大家可以看一看

  https://www.cnblogs.com/SYCstudio/p/7260613.html

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct node
{
    int x,y,c,next,other;
};
node a[2110000];
int len = 0,last[5000],st,ed;
int list[5000]; 
queue <int> qu;
void add(int x,int y,int w)
{
    int k1,k2;
    a[++len].next = last[x];
    k1 = len;
    a[len].x = x;
    a[len].y = y;
    a[len].c = w;
    last[x] = len;
    a[++len].next = last[y];
    k2 = len;
    a[len].x = y;
    a[len].y = x;
    a[len].c = 0;
    last[y] = len;
    a[k1].other = k2;
    a[k2].other = k1;
}
int h[5000];
bool bfs()
{
    memset(h,0,sizeof(h));
    h[st] = 1;
    int head,tail;
    list[1] = st;
    head = 1;
    tail = 2;
    while(head != tail)
    {
        int x = list[head];
//        cout<<x<<endl;
        for(int k = last[x];k;k = a[k].next)
        {
            int y = a[k].y;
//            cout<<k<<" "<<a[k].c<<" "<<y<<endl;
            if(a[k].c > 0 && h[y] == 0)
            {
                h[y] = h[x] + 1;
                list[tail++] = y;
//                cout<<y<<endl;
            }
        }
        head++;
    }
    /*for(int i = 1;i <= ed;i++)
    cout<<h[i]<<" ";
    cout<<endl;
    for(int i = 1;i <= len;i++)
    cout<<a[i].c<<" "; 
    cout<<endl;*/
    if(h[ed] > 0)
    return true;
    else
    return false;
}
int mymin(int x,int y){return x < y ? x : y;}
int find(int x,int f)
{
    if(x == ed)
    return f;
    int s = 0,t;
    for(int k = last[x];k;k = a[k].next)
    {
        int y = a[k].y;
        if(s < f && h[y] == (h[x] + 1) && a[k].c > 0)
        {
//            cout<<a[k].c<<" "<<f - s<<endl;
            t = find(y,mymin(a[k].c,f - s));
            s += t;
//            cout<<t<<endl;
            a[k].c -= t;
            a[a[k].other].c += t;
//            cout<<k<<"_"<<a[k].c<<" "<<a[k].other<<"_"<<a[a[k].other].c<<endl;
        }
    }
    if(s == 0)
    h[x] = 0;
    return s;
}
int main()
{
    int n,m;
    cin>>m>>n;
    st = 1;
    ed = n;
    len = 0;
    memset(last,0,sizeof(last)); 
    for(int i = 1;i <= m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
    }
//    cout<<endl;
    int s = 0,t;int l = 0;
    while(bfs() == true)
    {
        s += find(st,99999999);
    }
    cout<<s;
    return 0;
}
/*
4 4
1 2 10
2 4 5
2 3 20
3 4 10
*/

 

posted @ 2018-05-30 19:01  DukeLv  阅读(290)  评论(0编辑  收藏  举报