二分图/网络流/最小割/最大流/最小费用最大流等等 模板

Posted passione-123456

tags:

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

二分图匹配:

1.匈牙利算法  O(n * m)  n为二分图左侧点数  m为二分图右侧点数

技术图片
#include<bits/stdc++.h>
using namespace std;
const int N=1e7;
struct node{
    int from,to,nxt;
}e[N];
int head[N],cnt;
int n;
int v[N],ans,A,B,d[N];
void add(int from,int to){
    e[++cnt].nxt=head[from];
    e[cnt].from=from;
    e[cnt].to=to;
    head[from]=cnt;
    return;
}
bool ok(int from){
    for(int i=head[from];i;i=e[i].nxt){
        int to=e[i].to;
        if(!v[to]){
            v[to]=1;
            if(d[to]==-1||ok(d[to])){
                d[to]=from;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    scanf("%d%d%d",&A,&B,&n);
    for(int i=1;i<=n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        if(x>A||y>B)continue;
        add(x,y);
    }
    memset(d,-1,sizeof d);
    for(int i=1;i<=A;i++){
        for(int j=1;j<=B;j++)v[j]=0;
        if(ok(i))ans++;
    }
    printf("%d",ans);
}
Hungary

2.Dinic  O(n * √m)  n,m含义同上

技术图片
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=3000010;
int s,t,n,m,x,y,z,maxflow,deep[N],A,B;
struct Edge{
    int next,to,w;
}e[N];
int cnt=-1,head[N];
queue<int >q;
void add(int from,int to,int w){
    e[++cnt].next=head[from];
    e[cnt].to=to;
    e[cnt].w=w;
    head[from]=cnt;
}
bool bfs(int s,int t){
    memset(deep,0x3f,sizeof deep);
    while(!q.empty())q.pop();
    deep[s]=0;
    q.push(s);
    while(!q.empty()){
        int from=q.front();
        q.pop();
        for(int i=head[from];i!=-1;i=e[i].next){
            if(deep[e[i].to]==inf&&e[i].w){
                deep[e[i].to]=deep[from]+1;
                q.push(e[i].to);
            }
        }
    }
    if(deep[t]<inf)return 1;
    else return 0;
}
int dfs(int from,int t,int limit){
    if(!limit||from==t)return limit;
    int flow=0,f;
    for(int i=head[from];i!=-1;i=e[i].next){
        int to=e[i].to;
        if(deep[to]==deep[from]+1&&(f=dfs(to,t,min(limit,e[i].w)))){
            flow+=f;
            limit-=f;
            e[i].w-=f;
            e[i^1].w+=f;
            if(!limit)break;
        }
    }
    return flow;
}
void dinic(int s,int t){
    while(bfs(s,t)){
        maxflow+=dfs(s,t,inf);
    }
}
int main(){
    memset(head,-1,sizeof head);
    scanf("%d%d%d",&A,&B,&m);
    s=0;
    t=A+B+1;
    for(int i=1;i<=A;i++){
        add(s,i,1);
        add(i,s,0);
    }
    for(int i=A+1;i<=A+B;i++){
        add(i,t,1);
        add(t,i,0);
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        if(x>A||y>B)continue;
        y+=A;
        add(x,y,1);
        add(y,x,0);
    }
    dinic(s,t);
    printf("%d",maxflow);
    return 0;
}
Dinic

 

网络流:

1.Dinic  O(n* m)  n为点数  m为边数

技术图片
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int s,t,n,m,x,y,z,maxflow,deep[302000];
struct Edge{
    int next,to,w;
}e[305000];
int cnt=-1,head[300500],cur[300500];
queue<int >q;
void add(int from,int to,int w){
    e[++cnt].next=head[from];
    e[cnt].to=to;
    e[cnt].w=w;
    head[from]=cnt;
}
bool bfs(int s,int t){
    memset(deep,0x3f,sizeof deep);
    while(!q.empty())q.pop();
    deep[s]=0;
    q.push(s);
    while(!q.empty()){
        int from=q.front();
        q.pop();
        for(int i=head[from];i!=-1;i=e[i].next){
            if(deep[e[i].to]==inf&&e[i].w){
                deep[e[i].to]=deep[from]+1;
                q.push(e[i].to);
            }
        }
    }
    if(deep[t]<inf)return 1;
    else return 0;
}
int dfs(int from,int t,int limit){
    if(!limit||from==t)return limit;
    int flow=0,f;
    for(int i=head[from];i!=-1;i=e[i].next){
        int to=e[i].to;
        if(deep[to]==deep[from]+1&&(f=dfs(to,t,min(limit,e[i].w)))){
            flow+=f;
            limit-=f;
            e[i].w-=f;
            e[i^1].w+=f;
            if(!limit)break;
        }
    }
    return flow;
}
void dinic(int s,int t){
    while(bfs(s,t)){
        maxflow+=dfs(s,t,inf);
    }
}
int main(){
    memset(head,-1,sizeof head);
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,0);
    }
    dinic(s,t);
    printf("%d",maxflow);
    return 0;
}
Dinic

 

以上是关于二分图/网络流/最小割/最大流/最小费用最大流等等 模板的主要内容,如果未能解决你的问题,请参考以下文章

网络流问题

网络流24题-题目总结

网络流24题汇总

深谈网络流

网络流暂结(还差很多额)

734. [网络流24题] 方格取数问题 二分图点权最大独立集/最小割/最大流