poj 1273 Drainage Ditches (网络流 最大流)

  网络流模板题。

==========================================================================================================

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
const LL INF = 1e9+7;
const LL maxn = 1005;
const LL MOD = 1e9+7;
int n, m, Head[maxn], k;
int Pre[maxn];
bool vis[maxn];
struct Edge
{
    int from, to, w;
    int next;
}edge[maxn*2];

void Init()
{
    memset(Head, -1, sizeof(Head));
    memset(Pre, -1, sizeof(Pre));
}
void AddEdge(int s,int e,int w)
{
    edge[k].from = s;
    edge[k].to = e;
    edge[k].w = w;
    edge[k].next = Head[s];
    Head[s] = k ++;
}
bool BFS(int s,int e)///从源点到汇点找到一条路径
{
    memset(vis, false, sizeof(vis));
    queue<int> Q;
    Q.push(s);
    Pre[s] = -1;
    vis[s] = true;
    while( Q.size() )
    {
        int v = Q.front();
        Q.pop();
        if(v == e) return true;

        for(int i=Head[v]; i != -1; i = edge[i].next)
        {
            int to = edge[i].to;
            if( !vis[to] && edge[i].w )
            {
                vis[to] = true;
                Pre[to] = i;
                Q.push(to);
            }
        }
    }
    return false;
}

int Karp(int s,int e)
{
    int ans = 0;
    while( BFS(s, e) )///如果能找到路径就一直找
    {
        int MinFlow = INF, Cur = Pre[e];

        while(Cur != -1)
        {
            MinFlow = min(MinFlow, edge[Cur].w);
            Cur = Pre[edge[Cur].from];
        }
        ans += MinFlow;
        Cur = Pre[e];

        while(Cur != -1)
        {
            edge[Cur].w -= MinFlow;
            edge[Cur^1].w += MinFlow;
            Cur = Pre[edge[Cur].from];
        }
    }
    return ans;
}


int main()
{
    while(cin >> m >> n)
    {
        int s, e, w;
        Init();
        for(int i=0; i<m; i++)
        {
            scanf("%d %d %d", &s, &e, &w);
            AddEdge(s, e, w);
            AddEdge(e, s, 0);///增加的反向边
        }

        printf("%d
", Karp(1, n) );
    }
    return 0;
}

==========================================================================================================

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
const LL INF = 1e9+7;
const LL maxn = 1005;
const LL MOD = 1e9+7;
int n, m, Head[maxn], k;
int Depth[maxn];
bool vis[maxn];
struct node
{
    int s, e, flow;
    int next;
}edge[maxn*2];

void AddEdge(int s,int e,int flow)
{
    edge[k].s = s;
    edge[k].e = e;
    edge[k].flow = flow;
    edge[k].next = Head[s];
    Head[s] = k ++;
}


bool BfsDepth(int Star,int End)
{
    memset(Depth, 0, sizeof(Depth) );
    queue<int> Q;
    Depth[Star] = 1;
    Q.push(Star);

    while( Q.size() )
    {
        int s = Q.front();
        Q.pop();
        if(s == End) return true;

        for(int i=Head[s]; i != -1; i=edge[i].next)
        {
            int e = edge[i].e;
            if(!Depth[e] && edge[i].flow)
            {
                Q.push(e);
                Depth[e] = Depth[s] + 1;
            }
        }
    }
    return false;
}

int DFS(int s,int MaxFlow)///从s点发出的最大流量是MaxFlow
{
    if(s == n) return MaxFlow;
    int sFlow = 0;///sFlow 从

    for(int i=Head[s]; i != -1; i = edge[i].next)
    {
        int e = edge[i].e, flow = edge[i].flow;

        if(Depth[s]+1 == Depth[e] &&  flow)///到达下一层
        {
            flow = min(MaxFlow-sFlow, flow);
            flow = DFS(e, flow);
            edge[i].flow -= flow;
            edge[i^1].flow += flow;
            sFlow += flow;
            if(sFlow == MaxFlow)
                break;
        }
    }
    if(sFlow == 0)
        Depth[s] = 0;
    return sFlow;
}


int Dinic(int s,int e)
{
    int ans = 0;
    while(BfsDepth(s,e) == true)
    {
        ans += DFS(s, INF);
    }
    return ans;
}

int main()
{
    while(scanf("%d %d",&m, &n) != EOF)
    {
        int s, e, w;
        memset(Head, -1, sizeof(Head));
        k = 0;
        for(int i=0; i<m; i++)
        {
            scanf("%d %d %d", &s, &e, &w);
            AddEdge(s, e, w);
            AddEdge(e, s, 0);///添加反向边
        }
        printf("%d
", Dinic(1, n) );
    }
    return 0;
}
原文地址:https://www.cnblogs.com/chenchengxun/p/4849808.html