HDU1532Drainage Ditches(网络流Ford-Fulkerson模板)

网络流Ford-Fulkerson模板代码:

#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
using  namespace std;
const int N = 250;
const int INF = 0x3f3f3f3f;
struct Node
{
    int to;
    int cap;
    int rev;
};
vector<Node> v[N];
bool used[N];
void add_Node(int from, int to, int cap)
{
    v[from].push_back((Node){to, cap, v[to].size()});
    v[to].push_back((Node){from, 0, v[from].size() - 1});   //相当于前向星
}
int dfs(int s, int t, int f)
{
    if(s == t)
        return f;
    used[s] = true;
    for(int i = 0; i < v[s].size(); i++)
    {
        Node &tmp = v[s][i];
        if(used[tmp.to] == false && tmp.cap > 0)
        {
            int d = dfs(tmp.to, t, min(f, tmp.cap));
            if(d > 0)
            {
                tmp.cap -= d;
                v[tmp.to][tmp.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}
int max_flow(int s, int t)
{
    int flow = 0;
    for(;;)
    {
        memset(used, false, sizeof(used));
        int f = dfs(s, t, INF);
        if(f == 0)
            return flow;
        flow += f;
    }
}
int main()
{
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        memset(v, 0, sizeof(v));
        for(int i = 0; i < n; i++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            add_Node(x, y, z);
        }
        printf("%d\n", max_flow(1, m));
    }
    return 0;
}

Dinic模板:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, m, maxflow;//n点数, m边数
int edge[250][250];//邻接矩阵
int dis[250];//距源点的距离,分层图
int q[250];//BFS队列
int BFS()
{
    int u, v;
    memset(dis, -1, sizeof(dis));
    dis[1] = 0;
    int head = 0, tail = 1;
    q[1] = 1;
    while(head < tail)
    {
        u = q[++head];
        for(int v = 1; v <= n; v++)
            if(dis[v] < 0 && edge[u][v] > 0)
            {
                dis[v] = dis[u] + 1;
                q[++tail] = v;
            }
    }
    if(dis[n] > 0)
        return 1;
    else
        return 0;//汇点的DIS小于零,表明BFS不到汇点
}
//dinic代表一次增广,函数返回本次增广的流量,返回0表示无法增广
int dinic(int u, int low)Low是源点到现在最窄的(剩余流量最小)的边的剩余流量
{
    int flow;
    if(u == n)//是汇点
        return low;
    for(int v = 1; v <= n; v++)
        if(edge[u][v] > 0 && dis[v] == dis[u] + 1 && (flow = dinic(v, min(low, edge[u][v]))))//联通且是分层图的下一层且能到汇点(flow <> 0)
        {
            edge[u][v] -= flow;
            edge[v][u] += flow;
            return flow;
        }
    return 0;
}
int main()
{
    int u, v, w, flow;
    while(scanf("%d%d", &m, &n) != EOF)
    {
        memset(edge, 0, sizeof(edge));
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            edge[u][v] += w;
        }
        maxflow = 0;
        while(BFS())//要不停地建立分层图,如果BFS不到汇点才结束
        {
            while(flow = dinic(1, 0x3f3f3f3f))//一次BFS要不停地找增广路,直到找不到为止
                maxflow += flow;
        }
        printf("%d\n", maxflow);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值