altgo @ 2022-01-25 15:33:01
已经过题,但是时间比其他选手的劣很多。
希望能帮忙看一下,谢谢。
参考提交(别人的,总共59ms):https://www.luogu.com.cn/record/67846830
我的代码(总共279ms):
#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define go(i,a) for(int i=cur[a];i;i=edge[i].nxt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
const int N = 5005;
const int INF = 2e9;
int n, m;
struct nod {
int y, nxt;
int c;
}edge[N<<2];
int el = 1;
int Edgehead[N];
int dis[205];
int cur[205];
int S, T;
int q[205], head, tail;
void add (int x, int y, ll c) {
el++;
edge[el].y = y, edge[el].c = c, edge[el].nxt = Edgehead[x], Edgehead[x] = el;
return;
}
void ins (int x, int y, ll c) {
add (x, y, c);
add (y, x, 0ll);
return;
}
bool bfs () {
mem (dis, -1);
dis[S] = 0;
q[head = 1] = S, tail = 2;
while (head < tail) {
int x = q[head++];
cur[x] = 0;
for (int i = Edgehead[x]; i; i = edge[i].nxt) {
int y = edge[i].y;
if (edge[i].c && dis[y] == -1) {
if (!cur[x]) cur[x] = i;
dis[y] = dis[x] + 1;
q[tail++] = y;
}
}
}
return dis[T] != -1;
}
int dfs (int k, int flow) {
if (k==T || !flow) return flow;
int have = 0;
go (i,k) {
int y=edge[i].y;
if (dis[y] == dis[k]+1 && edge[i].c) {
int back = dfs (y, min(flow-have, edge[i].c));
have += back;
edge[i].c -= back;
edge[i^1].c += back;
if (have == flow)return flow;
}
cur[k] = edge[i].nxt;
}
dis[k] = -1;
return have;
}
int main () {
// freopen ("3376.in", "r", stdin);
mem (Edgehead, 0);
scanf ("%d %d %d %d", &n, &m, &S, &T);
fo (i,1,m) {
int x, y, c;
scanf ("%d %d %d", &x, &y, &c);
ins (x, y, c);
}
ll ans = 0;
while (bfs ()) {
ans += dfs (S, INF);
}
printf ("%lld\n", ans);
return 0;
}
by Computer1828 @ 2022-01-25 15:52:01
@altgo 你把 bfs 中改成这样既可:
bool bfs () {
for(int i = 0;i<=n+1;++i) dis[i] = -1,cur[i] = Edgehead[i];
dis[S] = 0;
q[head = 1] = S, tail = 2;
while (head < tail) {
int x = q[head++];
for (int i = Edgehead[x]; i; i = edge[i].nxt) {
int y = edge[i].y;
if (edge[i].c && dis[y] == -1) {
dis[y] = dis[x] + 1;
q[tail++] = y;
if(y == T) return true;
}
}
}
return false;
}
by altgo @ 2022-01-25 16:03:29
@Fmyh1828 感谢大佬!关注了。
不过为什么呢?
理论上流量为 0 的边就算在 DFS 过程中被遍历到也会直接被跳过。
为什么每次一定要将 cur[] 赋为第一条边呢?
by Computer1828 @ 2022-01-25 16:08:55
@altgo 我认为关键应该是只要找到一条增光路就可以进行dfs了,就不用一定要跑完全图。
by altgo @ 2022-01-25 16:13:57
@Fmyh1828 事实上,我的代码也是实现了这一点啊;并且,经过比较,我发现真正改善复杂度的关键在于将循环内对于 cur[x]=i 的赋值改到了外面首先 cur[x]=Edgehead[x] ;经过控制变量,发现在这一步上,复杂度实现了极大的优化。
想请教一下您为什么这样就会变得很快呢?
by Computer1828 @ 2022-01-25 16:24:03
@altgo 可能是减少了赋值运算量?
by altgo @ 2022-01-25 16:37:31
@Fmyh1828 这样吗?但是我感觉赋值对于时间复杂度的影响不会很大啊;而且好像也没有减少赋值运算量啊(
by Computer1828 @ 2022-01-25 16:47:48
@altgo 减少是肯定有的,你可以自己试一下。至于为什么会快那么多我也说不清
by altgo @ 2022-01-25 19:30:35
@Fmyh1828 谢谢DL