【网络流基础】hdu 1532 Drainage Ditches

题意:给出网络流的一些边,求节点1到节点n的最大流。
难度:0
题解:直接连边求最大流。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define forn(i,n) for(i=0;i<(n);i++)
#define for1(i,n) for(i=1;i<=(n);i++)
#define forh(i,u) for(i=head[u];i!=-1;i=edge[i].next)
#define inf (1<<29)
const int maxn = 222 , maxm = 555;
int n , m;
struct Edge {
    int u,v,c,next;
}edge[maxm];
int E,head[maxn];
int dist[maxn];
int que[maxn];
int sta[maxn];
void init() {
    E = 0; memset(head,-1,sizeof(head));
}
void _add(int u,int v,int c) {
    edge[E].u=u;edge[E].v=v;edge[E].c=c;edge[E].next=head[u];head[u]=E++;
}
void addedge(int u,int v,int c) {
    _add(u,v,c); _add(v,u,0);
}
int dinic(int s,int t) {
    int ans = 0;
    while(true) {
        int left,right,u,v,c,i;
        memset(dist,-1,sizeof(dist));
        left = right = 0;
        que[right ++] = s;
        dist[s] = 0;
        while(left < right) {
            u  = que[left ++];
            forh(i,u) {
                u=edge[i].u;
                v=edge[i].v;
                c=edge[i].c;
                if(c>0 && dist[v] == -1) {
                    dist[v] = dist[u] + 1;
                    que[right ++] = v;
                    if(v == t) {
                        left = right;
                        break;
                    }
                }
            }
        }
        if(dist[t] == -1) break;
        int top = 0;
        int now = s;
        while(true) {
            if(now != t) {
                forh(i,now) {
                    u=edge[i].u;
                    v=edge[i].v;
                    c=edge[i].c;
                    if(c > 0 && dist[u] + 1 == dist[v])
                        break;
                }
                if(i != -1) {
                    sta[top ++] = i;
                    now = edge[i].v;
                }
                else {
                    if(top == 0) break;
                    dist[edge[sta[--top]].v] = -1;
                    now = edge[sta[top]].u;
                }
            }
            else {
                int flow = inf , ebreak;
                forn(i,top)
                    if(flow > edge[sta[i]].c)
                        flow = edge[sta[ebreak = i]].c;
                ans += flow;
                forn(i,top) {
                    edge[sta[i]].c -= flow;
                    edge[sta[i]^1].c += flow;
                }
                now = edge[sta[top = ebreak]].u;
            }
        }
    }
    return ans;
}
int main() {
    while(~scanf("%d%d",&m,&n)) {
        init();
        while(m--) {
            int u , v , c;
            scanf("%d%d%d",&u,&v,&c);
            addedge(u,v,c);
        }
        int ans = dinic(1,n);
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值