Dinic求助
  • 板块学术版
  • 楼主_Atyou
  • 当前回复2
  • 已保存回复2
  • 发布时间2020/6/6 21:13
  • 上次更新2023/11/7 01:04:51
查看原帖
Dinic求助
26023
_Atyou楼主2020/6/6 21:13

其实之前已经困扰过我一会了,这会复习的时候又碰到了,大概是这样的:

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==0rest == 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

我感觉上后两者应该与第一个是等效的,不知为何会造成程序运行时间上的差异。如果有大佬知道的话,可以解答一下吗。如果程序不是等效的,可以解释一下区别在哪吗;如果是等效的,又是什么原因呢?

2020/6/6 21:13
加载中...