网络流模板

来源:互联网 发布:用友u8安装数据库 编辑:程序博客网 时间:2024/06/05 17:30


最大流


#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <queue>#include <algorithm>using namespace std;#define CLR( a , x ) memset ( a , x , sizeof (a) );const int maxm=1005;const int maxn=20;const int inf = 0x3f3f3f3f;struct Dinic{    struct Edge    {        int v,w,next;    }edge[maxm*2];    int tol,head[maxn],dis[maxn];    void addEdge(int u,int v,int w)    {        edge[tol].v=v,edge[tol].w=w,edge[tol].next=head[u];head[u]=tol++;        edge[tol].v=u,edge[tol].w=0,edge[tol].next=head[v];head[v]=tol++;    }    void init()    {        tol=0;        CLR(head,-1);    }    bool bfs(int s,int t)    {        queue<int>q;        q.push(s);        CLR(dis,-1);        dis[s]=0;        while(!q.empty())        {            int u=q.front();q.pop();            for(int i=head[u];i!=-1;i=edge[i].next)            {                int v=edge[i].v;                if( dis[v]<0 && edge[i].w)                {                    dis[v]=dis[u]+1;                    q.push(v);                }            }        }        return dis[t]!=-1;    }    int dfs(int s,int t,int low)    {        int flow;        if(t==s)   return low;        for(int i=head[s];i!=-1;i=edge[i].next)        {            int v=edge[i].v;            if(edge[i].w && (dis[v]==dis[s]+1) &&                (flow = dfs(v,t,min(low,edge[i].w))))            {                edge[i].w -= flow;                edge[i^1].w += flow;                return flow;            }        }        return 0;    }    int maxFlow(int s,int t)    {        int ans=0,tmp;        while(bfs(s,t))            while(tmp=dfs(s,t,inf))                ans+=tmp;        return ans;    }}DC;


使用例子:

int main(){    int t,m,n,a,b,c;//    RE    scanf("%d",&t);    for(int te=1;te<=t;te++)    {        DC.init();        scanf("%d%d",&n,&m);        while(m--)        {            scanf("%d%d%d",&a,&b,&c);            DC.addEdge(a,b,c);        }        printf("Case %d: %d\n",te,DC.maxFlow(1,n));    }    return 0;}


费用流模板用结构体包装后内存占用稍大,如果有严格内存限制的话就拆开来,基本是kuangbin的


最小费用流

求最大费用只需要取相反数,结果取相反数即可

#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <queue>#include <algorithm>using namespace std;#define CLR( a , x ) memset ( a , x , sizeof (a) );const int maxn = 200006;const int maxm = 100006;const int inf = 0x3f3f3f3f;struct minCostDinic {    struct Edge {        int to, next, cap, flow, cost;    } edge[maxm * 2];    int head[maxn], tol;    int pre[maxn], dis[maxn];    bool vis[maxn];    void init() {        tol = 0;        memset(head, -1, sizeof(head));    }    void addEdge(int u, int v, int cap, int cost) {        edge[tol].to = v;        edge[tol].cap = cap;        edge[tol].cost = cost;        edge[tol].flow = 0;        edge[tol].next = head[u];        head[u] = tol++;        edge[tol].to = u;        edge[tol].cap = 0;        edge[tol].cost = -cost;        edge[tol].flow = 0;        edge[tol].next = head[v];        head[v] = tol++;    }    bool spfa(int s, int t) {        queue<int>q;        memset(dis, inf, sizeof(dis));        memset(vis, false, sizeof(vis));        memset(pre, -1, sizeof(pre));        dis[s] = 0;        vis[s] = true;        q.push(s);        while (!q.empty()) {            int u = q.front();            q.pop();            vis[u] = false;            for (int i = head[u]; i != -1; i = edge[i].next) {                int v = edge[i].to;                if (edge[i].cap > edge[i].flow &&                        dis[v] > dis[u] + edge[i].cost ) {                    dis[v] = dis[u] + edge[i].cost;                    pre[v] = i;                    if (!vis[v]) {                        vis[v] = true;                        q.push(v);                    }                }            }        }        return pre[t] != -1;    }    //返回最大流,cost存最小费用    int minCostMaxflow(int s, int t, int &cost) {        int flow = 0;        cost = 0;        while (spfa(s, t)) {            int Min = inf;            for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) {                if (Min > edge[i].cap - edge[i].flow) {                    Min = edge[i].cap - edge[i].flow;                }            }            for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) {                edge[i].flow += Min;                edge[i ^ 1].flow -= Min;                cost += edge[i].cost * Min;            }            flow += Min;        }        return flow;    }} costDC;



0 0