过于玄学了,C++版本不一样,结果居然都不一样?
在本地和你谷IDE上都测过了测试点1(因为只看得到测试点1qwq)。本地能过,你谷IDE只要不吸氧都能过,吸了氧当场爆炸
当前弧优化加了,SPFA是反过来搜的最短路。用的vector邻接表,因为测得比前向星更快(
这是测试点1的数据Input:
10 10 2 5
8 10 862 53
9 4 968 98
4 10 653 79
2 7 237 97
3 9 326 76
1 3 108 8
7 5 994 86
4 9 705 38
1 8 135 18
8 1 252 64
和答案输出:
237 43371
以及性感代码求调(打空格属于是老年人码风力),为了方便各位大大检查,注释附上了:
#include <iostream>
#include <vector>
#include <cstring>
#include <bitset>
#include <queue>
using namespace std;
#define int long long
#define MS 5005
struct MinCostMaxFlow {
// vector存的邻接表,查e的反向边是g[e.to][e.rev]
struct edge {
int to, cap, rev, price;
};
vector<edge> g[MS];
int cur[MS], dis[MS];// cur:当前弧优化 dis:spfa最短路
bitset<MS> vis, inq;// vis:增广时用的标记 inq:spfa用的
void addeDirected(int a, int b, int capacity, int price) {// 加一条有向边
g[a].push_back({b, capacity, g[b].size(), price});
g[b].push_back({a, 0, g[a].size() - 1, -price});
}
bool spfa(int s, int t) {
memset(cur, 0, sizeof(cur));
memset(dis, 0x3f, sizeof(dis));
vis.reset();
// 上面3条是初始化
queue<int> q;
q.push(t);
inq[t] = true;
dis[t] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
inq[u] = false;
for (edge re : g[u]) {// 查的是反向边,因为是反过来的最短路
int v = re.to, w = -re.price;
if (g[v][re.rev].cap && dis[u] + w < dis[v]) {
dis[v] = dis[u] + w;
if (!inq[v]) {
inq[v] = true;
q.push(v);
}
}
}
}
return dis[s] != dis[0];// dis[0]用不上,就是inf嘛
}
int augment(int u, int t, int neck, int & cost) {// neck就是瓶颈,cost就是花费,返回流量
if (u == t)
return neck;
int flow = 0;
vis[u] = true;// 打上标记
for (int & idx = cur[u]; idx < g[u].size(); idx ++) {
edge & e = g[u][idx];
int v = e.to, w = e.price;
if (e.cap && !vis[v] && dis[u] == dis[v] + w) {
int add = augment(v, t, min(e.cap, neck), cost);
if (!add) {// 剪枝,但是好像没用,因为已经有vis的存在了
dis[v] = 0;
continue;
}
neck -= add;
e.cap -= add;
g[v][e.rev].cap += add;
flow += add;
cost += add * w;
}
if (neck == 0)
return flow;
}
return flow;
}
int spfaMCMF(int s, int t, int & cost) {
int flow = 0;
while (spfa(s, t))
while (int add = augment(s, t, dis[0], cost))
flow += add;
return flow;
}
} g;
// 主函数没啥好看的
main() {
ios :: sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m, s, t, flow, cost;
cin >> n >> m >> s >> t;
while (m --) {
int a, b, capacity, price;
cin >> a >> b >> capacity >> price;
g.addeDirected(a, b, capacity, price);
}
flow = g.spfaMCMF(s, t, cost);
cout << flow << ' ' << cost;
return 0;
}