没事可以骗分
费用流,顾名思义,就是有费用的流,也就是说,给一个网络流图中的每条弧增加一个单位流量费用。
一般来说求解的费用流都是最大流最小费用。
好像没什么好BB的
这里推荐使用zkw算法求解最小费用流,看着代码理解就行,应该还是很好理解的。
(zkw算法在稠密图上跑得飞快,在稀疏图上还不如直接SPFA)
#include <bits/stdc++.h> using namespace std; const int max_l = 1000005; const int maxdelta = 2e9; struct hazaking { int y, next, v, c; }e[max_l];//c表示这条边的单位流量费用 int linkk[max_l]; int t = 1; int dis[max_l], delta[max_l], q[max_l*10], p[max_l]; bool vis[max_l]; long long ans = 0; inline void insert(int x,int y,int z,int c) { e[++t].next = linkk[x]; e[t].y = y; e[t].v = z; e[t].c = c; linkk[x] = t; e[++t].next = linkk[y]; e[t].y = x; e[t].v = 0; e[t].c = -c;//反向边为负费用 linkk[y] = t; } inline int read() { int sum = 0, flag = 1; char c = getchar(); for (; c < '0' || c > '9' ; c = getchar()) if (c == '-') flag = -1; for (; c >= '0' && c <= '9'; c = getchar()) sum = (sum << 3) + (sum << 1) + c - 48; return sum * flag; } int n = read(), m = read(); inline bool spfa() { memset(vis, false, sizeof(vis)); for (int i = 1; i < n; i++) dis[i] = int (2e9);//初始化dis数组 dis[n] = 0; vis[n] = true; q[1] = n;//这里的SPFA是需要倒着跑的 int qh = 1, qt = 1; while (qh <= qt) { for (int i = linkk[q[qh]]; i ; i = e[i].next ) if (e[i^1].v && dis[e[i].y] > dis[q[qh]] - e[i].c )//由于是倒着跑,需要修改一下if { dis[e[i].y] = dis[q[qh]] - e[i].c;//修改dis if (!vis[e[i].y]) { vis[e[i].y] = true; q[++qt] = e[i].y;//入队 } } vis[ q[qh++] ] = false; } return dis[1] != int (2e9); } int dfs(int k,int delta) { vis[k] = true; if (k == n) return delta; int ma = 0, add; for (int i = linkk[k]; i && ma < delta; i = e[i].next) if (!vis[e[i].y] && e[i].v && dis[e[i].y] == dis[k] - e[i].c) { if (add = dfs(e[i].y, min(e[i].v, delta - ma))) { ans += add * e[i].c;//给最小费用加上费用,由于c是单位流量费用,这里要乘起来 e[i].v -= add; e[i ^ 1].v += add; ma += add; } } return ma; } inline int costflow() { int ans=0; while (spfa()) { vis[n] = true; while (vis[n]) { memset(vis, false, sizeof(vis)); ans+=dfs(1, maxdelta); } } return ans; } inline void init() { for (int i = 1; i <= m; i++) { int x = read(), y = read(), z = read(), c = read(); insert(x, y, z, c); } } inline void work() { printf("%d ",costflow());//求解最大流 printf("%lld\n",ans);//ans为最小费用 } int main() { init(); work(); }