[洛谷P1344][USACO4.4]追查坏牛奶Pollutant Control:最小割

分析:

最小割,为了保证边数尽量少可以将容量设为Ci*1001+1。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
typedef long long LL;

int n,m,ecnt=-1,head[40];
int dep[40],cur[40];
LL maxflow,mincut;
std::queue<int> q;
struct Edge{
    int to,nxt;
    LL cap;
}e[2005];

inline void add_edge(int bg,int ed,LL ca){
    ecnt++;
    e[ecnt].to=ed;
    e[ecnt].nxt=head[bg];
    e[ecnt].cap=ca;
    head[bg]=ecnt;
}

inline bool bfs(){
    memset(dep,0x3f,sizeof dep);
    for(int i=1;i<=n;i++) cur[i]=head[i];
    while(!q.empty()) q.pop();
    dep[1]=1;
    q.push(1);
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=e[i].nxt){
            int ver=e[i].to;
            if(dep[ver]>1e9&&e[i].cap){
                dep[ver]=dep[u]+1;
                q.push(ver);
            }
        }
    }
    return dep[n]<1e9;
}

LL dfs(int x,LL pref){
    if(x==n||!pref) return pref;
    LL flow=0,temp;
    for(int& i=cur[x];i!=-1;i=e[i].nxt){
        int ver=e[i].to;
        if(dep[ver]==dep[x]+1&&(temp=dfs(ver,std::min(pref,e[i].cap)))){
            e[i].cap-=temp;
            e[i^1].cap+=temp;
            pref-=temp;
            flow+=temp;
            if(!pref) break;
        }
    }
    return flow;
}

inline void dinic(){
    while(bfs()) maxflow+=dfs(1,1e18);
}

int main(){
    memset(head,-1,sizeof head);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;LL w;
        scanf("%d%d%lld",&u,&v,&w);
        add_edge(u,v,1001*w+1);
        add_edge(v,u,0);
    }
    dinic();
    mincut=maxflow;
    printf("%lld %lld\n",mincut/1001,mincut%1001);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9703969.html