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

来源:互联网 发布:双色球参选数据诈骗 编辑:程序博客网 时间:2024/06/05 04:21

网络流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
原创粉丝点击