其实之前已经困扰过我一会了,这会复习的时候又碰到了,大概是这样的:
int dinic(int x, int flow) {
if (x == id(n, m)) return flow;
int rest = flow, k;
for (int &i = cur[x]; i; i = nxt[i]) {
int y = ver[i];
if (cap[i] && dist[y] == dist[x] + 1) {
k = dinic(y, min(rest, cap[i]));
if (k == 0) dist[y] = -1;
cap[i] -= k;
cap[i ^ 1] += k;
rest -= k;
if (rest == 0) break;
}
}
return flow - rest;
}
这个没有出问题的代码,P4001结果:https://www.luogu.com.cn/record/34197016
但是现在有以下两份代码:
int dinic(int x, int flow) {
if (x == id(n, m)) return flow;
int rest = flow, k;
for (int &i = cur[x]; i && rest; i = nxt[i]) {
int y = ver[i];
if (cap[i] && dist[y] == dist[x] + 1) {
k = dinic(y, min(rest, cap[i]));
if (k == 0) dist[y] = -1;
cap[i] -= k;
cap[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
我大概之前是这么写的,大概就是把 rest==0 这个判断放到了循环里,感觉上与上个程序应该是等效的,但是会导致TLE。P4001结果:https://www.luogu.com.cn/record/34196990
我一直以为是不能丢在循环里的问题,今天又试了一下这样写:
int dinic(int x, int flow) {
if (x == id(n, m)) return flow;
int rest = flow, k;
for (int &i = cur[x]; i; i = nxt[i]) {
if (rest == 0) break;
int y = ver[i];
if (cap[i] && dist[y] == dist[x] + 1) {
k = dinic(y, min(rest, cap[i]));
if (k == 0) dist[y] = -1;
cap[i] -= k;
cap[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
发现也会TLE。P4001结果:https://www.luogu.com.cn/record/34196798
我感觉上后两者应该与第一个是等效的,不知为何会造成程序运行时间上的差异。如果有大佬知道的话,可以解答一下吗。如果程序不是等效的,可以解释一下区别在哪吗;如果是等效的,又是什么原因呢?