zkw费用流 java_网络流 - ZKW 费用流【代码】

#include

using namespace std;

namespace Basic {

template inline void read(Temp & res) {

Temp fh = 1; res = 0; char ch = getchar();

for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = 1;

for(; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ '0');

res = res * fh;

}

template inline void Checkmax(Temp num, Temp comp) {if(comp > num) num = comp;}

template inline void Checkmin(Temp num, Temp comp) {if(comp > num) num = comp;}

}

using namespace Basic;

const int Maxn = 5e3 + 5;

const int Maxm = 1e5 + 5;

int n, m, st, ed, x, y;

int z, h;

struct e {

int to, nxt;

int fl, cost;

} b[Maxm];

int head[Maxn], curr[Maxn], ecnt = 1;

int dis[Maxn];

void add(int u, int v, int w, int c) {b[++ecnt] = (e){v, head[u], w, c}; head[u] = ecnt;}

bool vis[Maxn];

queue q;

bool spfa() {

bool bl = 0;

memset(dis, 127, sizeof(dis));

while(!q.empty()) q.pop();

q.push(st); vis[st] = 1; dis[st] = 0;

while(!q.empty()) {

int tnow = q.front(); q.pop(); vis[tnow] = 0;

for(int i = head[tnow]; i; i = b[i].nxt) {

int tto = b[i].to, tw = b[i].fl, tc = b[i].cost;

if(!tw) continue;

if(dis[tnow] + tc < dis[tto]) {

dis[tto] = dis[tnow] + tc;

if(tto == ed) bl = 1;

if(!vis[tto]) {

q.push(tto);

vis[tto] = 1;

}

}

}

}

return bl;

}

int mincost, maxflow;

int dfs(int t, int flow) {

if(t == ed) return flow;

int rest = flow; vis[t] = 1;

for(int & i = curr[t]; i; i = b[i].nxt) {

int tto = b[i].to, tw = b[i].fl, tc = b[i].cost;

if(dis[t] + tc == dis[tto] && tw && (!vis[tto])) {

int k = dfs(tto, min(rest, tw));

if(!k) dis[tto] = -0x7fffffff;

mincost += k * b[i].cost; rest -= k, b[i].fl -= k, b[i ^ 1].fl += k;

if(!rest) break;

}

}

vis[t] = 0;

return flow - rest;

}

int main() {

read(n); read(m); read(st); read(ed);

while(m--) {

read(x); read(y); read(z); read(h);

add(x, y, z, h); add(y, x, 0, -h);

}

while(spfa()) {

memcpy(curr, head, sizeof(curr));

int now = 0;

while((now = dfs(st, 0x7fffffff))) maxflow += now;

}

printf("%d %d", maxflow, mincost);

return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值