网络流入门的心得

一、一句话描述网络流问题

  有向图,有多重边,每条边上有容量限制。指定起点和终点,求从起点到终点的最大容量。

二、一句话描述基本网络算法

  残量网络:考虑有向边,如果通过了正向流量,则消耗正向容量。同时增加反向流量。
  增广路径:考虑有向图,如果能够找到一条路,在当前流量状态下,能够从开始走到结束,且路径经过的最小容量大于零,则认为可以选择这条路径作为答案。
  最大流:每次找到“增广路径”,都将答案更新至残量网络中。直到某一次在完成搜索之后没能找到一条增广路径

三、一句话描述遇到的坑

  最开始看到增广路径概念之后把网络流当成了无向图模型。

四、一个列表表示网络流基础算法可以过得题

  http://hihocoder.com/problemset/problem/1369  

  http://acm.hdu.edu.cn/showproblem.php?pid=3549  

  http://poj.org/problem?id=1273

五、差不多通用的代码:

#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<string.h>
#include<math.h>

using namespace std;

#define ll long long
#define pp pair<ll,ll>
#define vecp vector<pp>
#define veci vector<int>

const ll MAXN=500+233;
const ll INF = 50000000+23333;
 

class edge
{
    public :
        ll a,b,c;
        edge(ll a,ll b,ll c)
        {
            this->a=a;
            this->b=b;
            this->c=c;
        }
        edge(){}
};

veci G[MAXN];
vector<edge> path;
ll vis[MAXN];
ll n,m;


void add_edge(ll a,ll b,ll c)
{
    // path.push_back(make)
    path.push_back(edge(a,b,c));
    G[a].push_back(path.size()-1);
    path.push_back(edge(b,a,0));
    G[b].push_back(path.size()-1);
    
}
ll dfs(ll now,ll minn)
{
    if(vis[now]||minn <= 0 )return 0;
    vis[now]=1;
    if(now == n)return minn;
    ll len = G[now].size();
    
    for(ll i=0;i<len;++i)
    {
        ll pos = G[now][i];
        ll tar = path[pos].b;
        ll mm = min(path[pos].c,minn);
        ll res = dfs(tar,mm);
        if(res)
        {
            path[pos].c -= res;
            path[pos^1].c += res;
            return res;
        }
    }return 0;
}
ll cases=0;

void init()
{
    cases++;
    for(ll i=0;i<=n;++i)G[i].clear();
    path.clear();
    memset(vis,0,sizeof(vis));
    
    for(ll i=0;i<m;++i)
    {
        ll a,b,c;
        cin>>a>>b>>c;
        add_edge(a,b,c);
    }
    
    ll res = dfs(1,INF);
    ll ans = res;
    while(res)
    {
        memset(vis,0,sizeof(vis));
        res = dfs(1,INF);
        ans += res;
    }
    cout<<ans<<endl;
    // prllf("Case %d: %d
",cases,ans);
}


int main()
{
    
    cin.sync_with_stdio(false);
    
    ll t=1 ;
    while(cin>>m>>n)init();
    // cin>>t;
    // for(ll i=0;i<t;++i)
    // {
        // cin>>m>>n;
        // init();
    // }
    // while(cin>>n>>m)init();
    
    
    return 0;
}

  

原文地址:https://www.cnblogs.com/rikka/p/8948426.html