UVA10330拆点最大流

本文详细介绍了如何使用Floyd-Warshall算法解决最大流问题,包括算法原理、实现步骤和实例解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 1000;
const int maxm = 100000;
const int inf = 10000000;
struct node{
    int v,flow,next;
}edge[maxm];
int head[maxn],dis[maxn];
int id,s,t,n,m;
void add_edge(int u,int v,int flow){
    edge[id].v = v;edge[id].flow = flow;edge[id].next =head[u];head[u] = id++;
    edge[id].v = u;edge[id].flow = 0   ;edge[id].next =head[v];head[v] = id++;
}
void init(){
    int flow;
    s = 0,t = n*2+2;//设置源点和汇点
    memset(head,-1,sizeof(head));id = 0;
    for(int i = 1; i <= n; i++){//拆点
        scanf("%d",&flow);
        add_edge(i,i+n,flow);
    }
    scanf("%d",&m);
    int u,v;
    while( m-- ){
        scanf("%d%d%d",&u,&v,&flow);
        add_edge(u+n,v,flow);
    }
    int b,d;
    scanf("%d%d",&b,&d);
    while( b-- ){
        scanf("%d",&v);
        add_edge(s,v,inf);
    }
    while( d --){
        scanf("%d",&u);
        add_edge(u+n,t,inf);
    }
}
bool bfs(){
    memset(dis,-1,sizeof(dis));
    queue<int>que;
    dis[s] = 0;
    que.push(s);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(int id = head[u]; id != -1; id = edge[id].next){
            int v = edge[id].v;
            if(edge[id].flow > 0 && dis[v] == -1 ){
                dis[v] = dis[u] + 1;
                que.push(v);
            }
        }
    }
    return dis[t] != -1;
}
int dinic(int u,int flow){
    if( u == t || flow == 0)return flow;
    int tmp = flow;
    for(int id = head[u]; id != -1; id = edge[id].next){
        int v = edge[id].v;
        if( edge[id].flow > 0 && dis[v] == dis[u] + 1){
            int tt = dinic(v,min(tmp,edge[id].flow));
            tmp -= tt;
            edge[id].flow -= tt;
            edge[id^1].flow += tt;
            if(tmp == 0)break;
        }
    }
    return flow - tmp;
}
int main(){
    //freopen("in.txt","r",stdin);
    while(~scanf("%d",&n)){
        init();
        int max_flow = 0;
        while(bfs())
        max_flow += dinic(s,inf);
        printf("%d\n",max_flow);
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/LUO257316/p/3229043.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值