[洛谷]最大流 模板

 P3376 【模板】网络最大流


开始我打的是假的网络流,深搜宽搜的临时变量存的都是边

明显变比点要多得多


这是EK

#include<stdio.h>
#include<string.h>
#define INF 1000000009
#define N 10010
int n,m,s,t,x,y,z,pre[N*20],way[N*20];
int head[N],next[N*20],to[N*20],flow[N*20],size;
int Q[N*20],front,rear;
int min(int a,int b) {
    return a<b ? a : b;
}
void add(int a,int b,int c) {
    size++;
    to[size]=b; flow[size]=c;
    next[size]=head[a];
    head[a]=size;
}
int bfs() {
    memset(pre,0,sizeof pre);
    front=0; rear=0;
    Q[rear++]=1;
    while(front<rear) {
        int d=Q[front++];
        for(int i=head[to[d]];i;i=next[i]) {
            if(!pre[i]&&flow[i]) {
                pre[i]=d;
                way[i]=min(flow[i],way[d]);
                if(to[i]==t) return i;
                Q[rear++]=i;
            }
        }
    }
    return 0;
}
int maxflow() {
    int ans=0;
    for(int delt,e;e=bfs();ans+=delt) {
        for(delt=way[e];e!=1;e=pre[e]) {
            flow[e]-=delt; flow[e^1]+=delt;
        }
    }
    return ans;
}
int main() {
    scanf("%d%d%d%d",&n,&m,&s,&t);
    add(0,s,INF); way[1]=INF;
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z); add(y,x,0);
    }
    printf("%d\n",maxflow());
}


..假的dinic

#include<stdio.h>
#include<string.h>
#define INF 1000000009
#define N 10010
int n,m,s,t,x,y,z,level[N*20];
int head[N],next[N*20],to[N*20],flow[N*20],size;
int Q[N*20],front,rear;
int min(int a,int b) {
    return a<b ? a : b;
}
void add(int a,int b,int c) {
    size++;
    to[size]=b; flow[size]=c;
    next[size]=head[a];
    head[a]=size;
}
int bfs() {
    memset(level,0,sizeof level);
    front=0; rear=0;
    level[1]=1;
    Q[rear++]=1;
    int link=0;
    while(front<rear) {
        int d=Q[front++];
        for(int i=head[to[d]];i;i=next[i]) {
            if(!level[i]&&flow[i]) {
                level[i]=level[d]+1;
                Q[rear++]=i;
                if(to[i]==t) link=1;
            }
        }
    }
    return link;
}
int dfs(int e,int minf) {
    if(to[e]==t||!minf) return minf;
    int f=0,delt;
    for(int i=head[to[e]];i;i=next[i]) {
        if(level[i]==level[e]+1&&(delt=dfs(i,min(minf,flow[i])))) {
            flow[i]-=delt; flow[i^1]+=delt;
            f+=delt; minf-=delt;
            if(!minf) break;
        }
    }
    return f;
}
int maxflow() {
    int ans=0;
    while(bfs()) {
        ans+=dfs(1,INF);
    }
    return ans;
}
int main() {
    scanf("%d%d%d%d",&n,&m,&s,&t);
    add(0,s,INF);
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z); add(y,x,0);
    }
    printf("%d\n",maxflow());
}


..真的dinic

#include<stdio.h>
#include<string.h>
#define INF 1000000009
#define N 10010
int n,m,s,t,x,y,z,level[N];
int head[N],next[N*20],to[N*20],flow[N*20],size=1;
int Q[N*20],front,rear;
int min(int a,int b) {
    return a<b ? a : b;
}
void add(int a,int b,int c) {
    size++;
    to[size]=b; flow[size]=c;
    next[size]=head[a];
    head[a]=size;
}
int bfs() {
    memset(level,0,sizeof level);
    front=0; rear=0;
    level[s]=1;
    Q[rear++]=s;
    while(front<rear) {
        int d=Q[front++];
        for(int i=head[d];i;i=next[i]) {
            if(!level[to[i]]&&flow[i]) {
                level[to[i]]=level[d]+1;
                if(to[i]==t) return 1;
                Q[rear++]=to[i];
            }
        }
    }
    return 0;
}
int dfs(int u,int minf) {
    if(u==t) return minf;
    int f=0,delt;
    for(int i=head[u];i;i=next[i]) {
        if(level[to[i]]==level[u]+1&&(delt=dfs(to[i],min(minf,flow[i])))) {
            flow[i]-=delt; flow[i^1]+=delt;
            f+=delt; minf-=delt;
            if(!minf) break;
        }
    }
    return f;
}
int maxflow() {
    int ans=0;
    while(bfs()) {
        ans+=dfs(s,INF);
    }
    return ans;
}
int main() {
    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);
    }
    printf("%d\n",maxflow());
}


然后用dinic A了一些水题


 P2756 飞行员配对方案问题

#include<stdio.h>
#include<string.h>
#define N 105
#define INF 1000000007
int m,n,x,y,level[N];
int head[N],next[N*N*2],to[N*N*2],flow[N*N*2],size=1;
int Q[N*N*2],front,rear;
int min(int a,int b) {
    return a<b ? a : b;
}
void add(int a,int b,int c) {
    size++;
    to[size]=b; flow[size]=c;
    next[size]=head[a];
    head[a]=size;
}
int bfs() {
    memset(level,0,sizeof level);
    front=0; rear=0;
    level[0]=1;
    Q[rear++]=0;
    while(front<rear) {
        int d=Q[front++];
        for(int i=head[d];i;i=next[i]) {
            if(!level[to[i]]&&flow[i]) {
                level[to[i]]=level[d]+1;
                if(to[i]==n+1) return 1;
                Q[rear++]=to[i];
            }
        }
    }
    return 0;
}
int dfs(int u,int maxf) {
    if(u==n+1||!maxf) return maxf;
    int f=0,delt;
    for(int i=head[u];i;i=next[i]) {
        if(level[to[i]]==level[u]+1&&(delt=dfs(to[i],min(maxf,flow[i])))) {
            flow[i]-=delt; flow[i^1]+=delt;
            f+=delt; maxf-=delt;
            if(!maxf) break;
        }
    }
    return f;
}
int maxflow() {
    int ans=0;
    while(bfs()) {
        ans+=dfs(0,INF);
    }
    return ans;
}
int main() {
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++) {
        add(0,i,1); add(i,0,0);
    }
    for(int i=m+1;i<=n;i++) {
        add(i,n+1,1); add(n+1,i,0);
    }
    while(scanf("%d%d",&x,&y)&&x!=-1) {
        add(x,y,1); add(y,x,0);
    }
    printf("%d\n",maxflow());
    for(int i=1;i<=m;i++) {
        for(int j=head[i];j;j=next[j]) {
            if(!flow[j]&&to[j]>m&&to[j]<=n) {
                printf("%d %d\n",i,to[j]);
                break;
            }
        }
    }
}

 P1343 地震逃生

#include<stdio.h>
#include<string.h>
#define N 205
#define INF 1000000007
int n,m,k,x,y,z,level[N];
int head[N],next[N*20],to[N*20],flow[N*20],size=1;
int Q[N*20],front,rear;
int min(int a,int b) {
    return a<b ? a : b;
}
void add(int a,int b,int c) {
    size++;
    to[size]=b; flow[size]=c;
    next[size]=head[a];
    head[a]=size;
}
int bfs() {
    memset(level,0,sizeof level);
    front=0; rear=0;
    level[1]=1;
    Q[rear++]=1;
    while(front<rear) {
        int d=Q[front++];
        for(int i=head[d];i;i=next[i]) {
            if(!level[to[i]]&&flow[i]) {
                level[to[i]]=level[d]+1;
                if(to[i]==n) return 1;
                Q[rear++]=to[i];
            }
        }
    }
    return 0;
}
int dfs(int u,int minf) {
    if(u==n||!minf) return minf;
    int f=0,delt;
    for(int i=head[u];i;i=next[i]) {
        if(level[to[i]]==level[u]+1&&(delt=dfs(to[i],min(minf,flow[i])))) {
            flow[i]-=delt; flow[i^1]+=delt;
            f+=delt; minf-=delt;
            if(!minf) break;
        }
    }
    return f;
}
int maxflow() {
    int ans=0;
    while(bfs()) {
        ans+=dfs(1,INF);
    }
    return ans;
}
int main() {
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z); add(y,x,0);
    }
    int once=maxflow();
    if(!once) puts("Orz Ni Jinan Saint Cow!");
    else printf("%d %d\n",once,(k-1)/once+1);
}

 P3386 【模板】二分图匹配

嗯这用的是匈牙利算法..
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 1005
using namespace std;
int n,m,e,x,y;
int g[N*2][N*2],vis[N*2],link[N*2];
int dfs(int u) {
    for(int i=n+1;i<=n+m;i++) {
        if(!vis[i]&&g[u][i]) {
            vis[i]=1;
            if(!link[i]||dfs(link[i])) {
                link[i]=u; return 1;
            }
        }
    }
    return 0;
}
int hungary() {
    int ret=0;
    for(int i=1;i<=n;i++) {
        memset(vis,0,sizeof vis);
        ret+=dfs(i);
    }
    return ret;
}
void input() {
    scanf("%d%d%d",&n,&m,&e);
    for(int i=1;i<=e;i++) {
        scanf("%d%d",&x,&y);
        if(x<=n&&y<=m) {
            g[x][n+y]=1;
        }
    }
}
int main() {
    input();
    printf("%d\n",hungary());
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值