网络流算法

Dinic算法

#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
const int INF=1e9+7;
const int maxn=205;
int N,M,S,T;
struct edge
{
    int u,v,cap,flow;
    edge(int u=0,int v=0,int cap=0,int flow=0)
    :u(u),v(v),cap(cap),flow(flow){}
}E[maxn*maxn];
int eid; //要初置为0
vector<int> G[maxn];
void init()
{
    eid=0;
    for(int i=0;i<maxn;i++) G[i].clear();
}
void AddEdge(int u,int v,int cap)
{
    E[eid]=edge(u,v,cap,0);
    G[u].push_back(eid++);
    E[eid]=edge(v,u,0,0);
    G[v].push_back(eid++);
}
bool vis[maxn];
int d[maxn],cur[maxn];
queue<int> que;
bool BFS()
{
    memset(vis,false,sizeof(vis));
    while(!que.empty()) que.pop();
    vis[S]=true;
    d[S]=0;
    que.push(S);
    while(!que.empty())
    {
        int u=que.front();  que.pop();
        int Size=G[u].size();
        for(int i=0;i<Size;i++)
        {
            int id=G[u][i];
            edge& e=E[id];
            int v=e.v;
            if(!vis[v]&&e.cap>e.flow)
            {
                vis[v]=true;
                d[v]=d[u]+1;
                que.push(v);
            }
        }
    }
    return vis[T];
}
int DFS(int u,int a)
{
    if(u==T||a==0) return a;
    int ret=0,f;
    int Size=G[u].size();
    for(int& i=cur[u];i<Size;i++)
    {
        int id=G[u][i];
        edge& e=E[id];
        int v=e.v;
        if(d[u]+1==d[v]&&(f=DFS(v,min(a,e.cap-e.flow)))>0)
        {
            ret+=f;
            e.flow+=f;
            E[id^1].flow-=f;
            a-=f;
            if(a==0) break;
        }
    }
    return ret;
}
int MaxFlow(int s,int t)
{
    S=s; T=t;
    int ret=0;
    while(BFS())
    {
        memset(cur,false,sizeof(cur));
        ret+=DFS(S,INF);
    }
    return ret;
}
View Code

EK算法

struct edge
{
    int from,to,cap,flow;
    edge(int from=0,int to=0,int cap=0,int flow=0)
    :from(from),to(to),cap(cap),flow(flow){}
};
vector<edge> save;
vector<int> G[105];
void addedge(int from,int to,int cap,int flow)
{
    save.push_back(edge(from,to,cap,flow));
    save.push_back(edge(to,from,0,flow));
    int id=save.size();
    G[from].push_back(id-2);
    G[to].push_back(id-1);
}
int add[105],fa[105];
int MaxFlow(int be,int en)
{
    int ret=0;
    while(true)
    {
        memset(add,0,sizeof(add));
        queue<int> que;
        que.push(be);
        add[be]=INF;
        while(!que.empty())
        {
            int from=que.front();  que.pop();
            for(int i=0;i<G[from].size();i++)
            {
                edge e=save[G[from][i]];
                int to=e.to,cap=e.cap,flow=e.flow;
                if(!add[to]&&cap>flow)
                {
                    fa[to]=G[from][i];
                    add[to]=min(add[from],cap-flow);
                    que.push(to);
                }
            }
            if(add[en])  break;
        }
        if(!add[en])  break;
        for(int st=en;st!=be;st=save[fa[st]].from)
        {
            save[fa[st]].flow+=add[en];
            save[fa[st]^1].flow-=add[en];
        }
        ret+=add[en];
    }
    return ret;
}
View Code

最小费最大流算法

struct edge
{
    int u,v;
    int cap,flow,cost;
    edge(int u=0,int v=0,int cap=0,int flow=0,int cost=0)
    :u(u),v(v),cap(cap),flow(flow),cost(cost){}
}save[4*maxn*maxn];
struct MFMC
{
    int n,edge_num;
    vector<int> G[maxn];
    void init(int nn)
    {
        n=nn;
        edge_num=0;
        for(int i=0;i<=n;i++) G[i].clear();
    }
    void addedge(int u,int v,int cap,int cost)
    {
        int a=edge_num++;
        int b=edge_num++;
        save[a]=edge(u,v,cap,0,cost);
        save[b]=edge(v,u,0,0,-cost);
        G[u].push_back(a);
        G[v].push_back(b);
    }
    int add[maxn],C[maxn];
    int fa[maxn];
    bool inq[maxn];
    void clr(int s)
    {
        for(int i=0;i<=n;i++) add[i]=0,inq[i]=false,C[i]=INF;
        add[s]=INF; inq[s]=true; C[s]=0;
        fa[s]=0;
    }
    int solve(int s,int t)
    {
        int cnt=0,ret=0;
        while(true)
        {
            clr(s);
            queue<int> que;
            que.push(s);
            while(!que.empty())
            {
                int u=que.front();  que.pop();
                inq[u]=false;
                int Size=G[u].size();
                for(int i=0;i<Size;i++)
                {
                    int edge_id=G[u][i];
                    edge& e=save[edge_id];
                    int v=e.v;
                    int cap=e.cap,flow=e.flow,cost=e.cost;
                    if(cap>flow&&C[v]>C[u]+cost)
                    {
                        C[v]=C[u]+cost;
                        fa[v]=edge_id;
                        add[v]=min(add[u],cap-flow);
                        if(!inq[v]){ inq[v]=true; que.push(v); }
                    }
                }
            }
            if(!add[t])  break;
            cnt+=add[t];
            ret+=add[t]*C[t];
            for(int st=t;st!=s;st=save[fa[st]].u)
            {
                int a=fa[st],b=fa[st]^1;
                save[a].flow+=add[t];
                save[b].flow-=add[t];
            }
       }
       return ret;
    }
};
View Code

 

posted @ 2016-07-26 10:00  wust_ouyangli  阅读(178)  评论(0编辑  收藏  举报