网络流之最大流和最小费用流

Posted 175426-hzau-zxjc-con

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流之最大流和最小费用流相关的知识,希望对你有一定的参考价值。

最大流

邻接矩阵

const int N=505;
const int inf=0x3f3f3f3f;
int mp[N][N],vis[N];
int dfs(int s,int t,int f)
{
    if(s==t)return f;
    vis[s]=1;
    for(int i=1;i<=n;i++)
    {
        if(mp[s][i]>0&&!vis[i])
        {
            int d=dfs(i,t,min(f,mp[s][i]));
            if(d>0)
            {
                mp[s][i]+=d;
                mp[i][s]-=d;
                return d;
            }
        }
    }
}
int maxflow(int s,int t)
{
    int flow=0;
    while(1)
    {
        memset(vis,0,sizeof vis);
        int f=dfs(s,t,inf);//找到从s到t的增广路
        if(f==0)return flow;//找不到了就回去
        flow+=f;//找到一个流量为f的增广路
    }
}

邻接表

const int inf=0x3f3f3f3f;
const int N=505;
int vis[N];
struct Node
{
    int to,cap,idx;
    NOde(){}
    NOde(int x,int y,int z):to(x),cap(y),idx(z);
};
vector<NOde>node[N];
void add(int u,int v,int w)
{
    node[u].push_back(NOde(v,w,node[v].size()));
    node[v].push_back(NOde(u,0,node[u].size()-1));
}
int dfs(int s,int t,int f)
{
    if(s==t)return f;
    vis[s]=1;
    for(int i=0;i<=node[s].size();i++)
    {
        Node &cur=node[s][i];
        if(!vis[cur.to]&&cur.cap>0)
        {
            int tem=dfs(cur.to,t,min(f,cur.cap));
            if(tem>0)
            {
                cur.cap-=tem;
                node[cur.to][cur.idx].cap+=tem;
                return tem;
            }
        }
    }
    return 0;
}
int maxflow(int s,int t)
{
    int sum=0;
    while(1)
    {
        memeset(vis,0,sizeof vis);
        int flow=dfs(s,t,inf);
        if(flow==0)return sum;
        sum+=flow;
    }
}

前向星

const int maxn=1005;
const int N=505;
const int inf=0x3f3f3f3f;
int tot,head[maxn];
bool vis[maxn];
struct Node
{
    int to,cap,next;
    Node(){}
    Node(int x,int y,int z):to(x),cap(y),next(z);
}node[N*N*2];
void add(int u,int v)
{
    node[tot]=Node(v,1,head[u]);
    head[u]=tot++;
    nod[tot]=NOde(u,0,head[v]);
    head[v]=tot++;
}
void emp()
{
    memeset(head,-1,sizeof head);
    tot=0;
}
int dfs(int s,int t,int f)
{
    if(s==t)return f;
    vis[s]=true;
    for(int i=head[s];i!=-1;i=node[i].next)
    {
        Node &cur=node[i];
        if(!vis[cur.to]&&cur.cap>0)
        {
            int tem=dfs(cur.to,t,min(f,cur.cap));
            if(tem>0)
            {
                cur.cap-=tem;
                node[i^1].cap+=tem;
                return tem;
            }
        }
    }
    return 0;
}
int maxflow(int s,int t)
{
    int sum=0;
    while(1)
    {
        memeset(vis,0,sizeof vis);
        int flow=dfs(s,t,inf);
        if(flow==0)return sum;
        sum+=flow;
    }
}

EK

const int inf=0x3f3f3f3f;
const int maxn=105;
int c[maxn][maxn],f[maxn][maxn],p[maxn],a[maxn];
int bfs()
{
    queue<int >q;
    memset(p,-1,sizeof p);
    memset(a,0,sizeof a);
    a[s]=inf;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=1;i<=t;i++)
        {
            if(!a[i]&&c[u][i]>f[u][i])
            {
                p[i]=u;
                q.push(i);
                a[i]=min(a[u],c[u][i]-f[u][i]);
            }
        }
        if(a[t])break;
    }
    if(!a[t])return 0;
    for(int u=t;u!=s;u=p[u])
    {
        f[p[u]][u]+=a[t];
        f[u][p[u]]-=a[t];
    }
    return a[t];
}
int EK()
{
    int sum=0;
    while(1)
    {
        int tmp=bfs();
        if(tmp==0)return sum;
        sum+=tmp;
    }
}

Dinic

const int inf=0x3f3f3f3f;
const int maxn=405;
int c[maxn][maxn],dep[maxn];
int s,t;
bool bfs()
{
    queue<int>q;
    memset(dep,-1,sizeof dep);
    dep[s]=0;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int v=1;v<=t;v++)
        {
            if(c[u][v]>0&&dep[v]=-1)
            {
                dep[v]=dep[u]+1;
                q.push(v);
            }
        }
    }
    return dep[t]!=-1;
}
int dfs(int u,int flow)
{
    if(u==t)return flow;
    int tmp;
    for(int v=1;v<=t;v++)
    {
        if(c[u][v]>0&&dep[v]=dep[u]+1&&(tmp=dfs(v,min(flow,c[u][v])));
        {
            c[u][v]-=tmp;
            c[v][u]+=tmp;
            return tmp;
        }
    }
    return 0;
}
int Dinic()
{
    int res=0;
    while(bfs())
    {
        while(tmp=dfs(s,inf))
        {
            res+=tmp;
        }
    }
    return res;
}

最小费用流

SPFA

const int inf=0x3f3f3f3f;
const int maxn=405;
int c[maxn][maxn],dep[maxn];
int s,t;
bool bfs()
{
    queue<int>q;
    memset(dep,-1,sizeof dep);
    dep[s]=0;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int v=1;v<=t;v++)
        {
            if(c[u][v]>0&&dep[v]=-1)
            {
                dep[v]=dep[u]+1;
                q.push(v);
            }
        }
    }
    return dep[t]!=-1;
}
int dfs(int u,int flow)
{
    if(u==t)return flow;
    int tmp;
    for(int v=1;v<=t;v++)
    {
        if(c[u][v]>0&&dep[v]=dep[u]+1&&(tmp=dfs(v,min(flow,c[u][v])));
        {
            c[u][v]-=tmp;
            c[v][u]+=tmp;
            return tmp;
        }
    }
    return 0;
}
int Dinic()
{
    int res=0;
    while(bfs())
    {
        while(tmp=dfs(s,inf))
        {
            res+=tmp;
        }
    }
    return res;
}

 

以上是关于网络流之最大流和最小费用流的主要内容,如果未能解决你的问题,请参考以下文章

网络流:最大流之SAP算法

网络流总结费用流

模板最小费用最大流

[洛谷P3381]模板最小费用最大流

HDU 3435A new Graph Game(网络流之最小费用流)

模板最小费用最大流