网络流算法汇总

大部分都是参考gty神犇的,,,
大爱dinic:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#define inf 1e9
#define N 202
using namespace std;
struct edge{ int nxt,point,v,remain;};
edge e[N*N];
int cnt,level[N],cur[N],n,m,s,t;
void add(int u1,int v1,int w1){
    e[++cnt].nxt=e[u1].point; e[u1].point=cnt; e[cnt].v=v1; e[cnt].remain=w1;}
void adds(int u1,int v1,int w1){ add(u1,v1,w1); add(v1,u1,0);}
int getnum(){
    char c; int num;
    while (!isdigit(c=getchar()));
    num=c-'0';
    while (isdigit(c=getchar())) num=num*10+c-'0';
    return num;
}

void init(){
    cnt=-1;
    m = getnum(); n = getnum();
    for (int i=0;i<=m<<2;++i) { e[i].point=e[i].nxt=-1; }
    for (int i = 1;i <= m;++i){
        int u1=getnum(),v1=getnum(),w1=getnum();
        adds(u1,v1,w1);}
}

inline bool bfs(int s,int t){
    int que[N],head=0,tail=1;
    for (int i=1;i<=n;++i) cur[i]=e[i].point;
    memset(level,0x7f,sizeof(level));
    memset(que,0,sizeof(que))
;   level[s]=0; que[1]=s;
    while (head<tail){
        int x=que[++head];
        for (int p=e[x].point;p!=-1;p=e[p].nxt){
            if (level[e[p].v]>inf && e[p].remain) {
               que[++tail]=e[p].v;
               level[e[p].v]=level[x]+1;}
        }
    }
    return level[t] < inf;
}

inline int dfs(int now,int t,int limit){
    int f,flow=0;
    if (now==t||!limit) return limit;
    for (int p=cur[now];p!=-1;p=e[p].nxt){
        cur[now]=p;
        if (level[e[p].v]==level[now]+1&&(f=dfs(e[p].v,t,min(e[p].remain,limit)))){
            flow+=f;
            limit-=f;
            e[p].remain-=f;
            e[p^1].remain+=f;
            if (!limit) break;
        }
    }
    return flow;
}

int dinic(int s,int t){
    int max_flow=0;
    while (bfs(s,t)) max_flow+=dfs(s,t,inf);
    return max_flow;
}

int main(){
    init();
    printf("%d",dinic(1,n));
    return 0;
}

费用流:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#define maxne 1003
#define maxnv 1002
#define inf 1e9
using namespace std;
struct edge{ int point,nxt,v,remain,cost;};
edge e[maxne];
int cnt,n,m,mincost,max_flow,dis[maxnv],que[maxnv],lastedge[maxnv];
bool used[maxnv];
void addedge(int u1,int v1,int w1,int w2){
  e[++cnt].nxt=e[u1].point;e[u1].point=cnt;e[cnt].v=v1;e[cnt].remain=w1;e[cnt].cost=w2;}
void adds(int u1,int v1,int w1,int w2){ addedge(u1,v1,w1,w2); addedge(v1,u1,0,-w2);}
int getnum(){
    char c; int num;
    while (!isdigit(c=getchar()));
    num=c-'0';
    while (isdigit(c=getchar())) num=num*10+c-'0';
    return num;
}

void init(){
    cnt=-1;
    n=getnum(); m=getnum();
    memset(e,-1,sizeof(e));
    for (int i=1;i<=m;++i){
        int u1=getnum(),v1=getnum(),w1=getnum(),w2=getnum();
        adds(u1,v1,w1,w2);
    }
}

inline int add_flow(int s,int t){
    int now=t,add=inf;
    while (now!=s){
        add=min(add,e[lastedge[now]].remain);
        now=e[lastedge[now]^1].v;
    }
    now=t;
    while (now!=s){
        e[lastedge[now]].remain-=add;
        e[lastedge[now]^1].remain+=add;
        now=e[lastedge[now]^1].v;
    }
    return add;
}

inline bool spfa(int s,int t,int& max_flow,int& mincost){
    int head=0,tail=1;
    memset(dis,0x7f,sizeof(dis));
    memset(que,0,sizeof(que));
    memset(used,0,sizeof(used));
    memset(lastedge,-1,sizeof(lastedge));
    que[1]=s; dis[s]=0; used[s]=1;
    while (head<tail){
        int x=que[++head]; used[x]=0;
        for (int p=e[x].point;p!=-1;p=e[p].nxt)
          if (e[p].remain&&dis[x]+e[p].cost<dis[e[p].v]){
             dis[e[p].v]=dis[x]+e[p].cost;
             lastedge[e[p].v]=p;
             if (!used[e[p].v]) que[++tail]=e[p].v;
             used[e[p].v]=1;
          }
    }
    if (dis[t]>inf) return 0;
    int add=add_flow(s,t);
    max_flow+=add;
    mincost+=add*dis[t];
    return 1;
}

inline void mfmc(int& max_flow,int& mincost){
    max_flow=mincost=0;
    while (spfa(1,n,max_flow,mincost));
}

int main(){
    init();
    mfmc(max_flow,mincost);
    printf("%d %d",max_flow,mincost);
    return 0;
}

你可能感兴趣的:(网络流算法汇总)