这里贴些曾经写网络流时犯过的沙雕错误QAQ
可能对自己、对找不出网络流错误的人有些帮助
网络最大流/最小割
I 写前向星时,tot初值误赋为0
错误:
int hd[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot;
正确:
int hd[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot(1);
II 在深搜中,枚举点时,为了方便,终点误用全局变量存储
错误原因:深搜后全局变量的值会改变
错误:
int DFS( int x, int fl ){
if ( x == T ) return fl;
int res(fl), k;
for ( int i = hd[x]; i && res; i = nxt[i] ){
y = to[i];
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( res, val[i] ) );
if ( !k ) d[y] = 0;
val[i] -= k; val[i^1] += k; res -= k;
}
}
return fl - res;
}
正确
int DFS( int x, int fl ){
if ( x == T ) return fl;
int res(fl), k;
for ( int i = hd[x]; i && res; i = nxt[i] ){
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( res, val[i] ) );
if ( !k ) d[to[i]] = 0;
val[i] -= k; val[i^1] += k; res -= k;
}
}
return fl - res;
}
III 变量搞错
第一种
点、边下标弄错
第二种
二维矩阵时N、M弄反
第三种
to[i]与i搞不清
IV ans没赋初值
不说了。。。丢脸
V 源点搞错
都用了变量S了,咋还写成1 丢脸
VI 忘了建反边
从今天开始,网络最大流/最小割的建边都这么写
void Add( int x, int y, int z ){
nxt[++tot] = hd[x]; hd[x] = tot; to[tot] = y; val[tot] = z;
nxt[++tot] = hd[y]; hd[y] = tot; to[tot] = x; val[tot] = 0;
}
VII 宽搜时忘了pop
丢脸
VIII DFS时res为0时未及时退出
错误:
int DFS( int x, int fl ){
if ( x == T ) return fl;
int res(fl), k;
for ( int &i = HD[x]; i; i = nxt[i] ){
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( res, val[i] ) );
if ( !k ) d[to[i]] = 0;
res -= k; val[i] -= k; val[i ^ 1] += k;
}
}
return fl - res;
}
正确:
int DFS( int x, int fl ){
if ( x == T ) return fl;
int res(fl), k;
for ( int &i = HD[x]; i && res; i = nxt[i] ){
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( res, val[i] ) );
if ( !k ) d[to[i]] = 0;
res -= k; val[i] -= k; val[i ^ 1] += k;
}
}
return fl - res;
}
后果:超时
IX d数组没有初始化
错误:
bool BFS(){
while( !Q.empty() ) Q.pop();
d[S] = 1; Q.push(S);
while( !Q.empty() ){
int t(Q.front()); Q.pop();
for ( int i = hd[t]; i; i = nxt[i] ){
if ( val[i] && !d[to[i]] ){
Q.push(to[i]); d[to[i]] = d[t] + 1;
if ( to[i] == T ) return 1;
}
}
}
return 0;
}
正确:
bool BFS(){
while( !Q.empty() ) Q.pop();
memset( d, 0, sizeof d );
d[S] = 1; Q.push(S);
while( !Q.empty() ){
int t(Q.front()); Q.pop();
for ( int i = hd[t]; i; i = nxt[i] ){
if ( val[i] && !d[to[i]] ){
Q.push(to[i]); d[to[i]] = d[t] + 1;
if ( to[i] == T ) return 1;
}
}
}
return 0;
}
X 深搜时到达汇点忘记return
Wrong:
int DFS( int x, int fl ){
int res(fl), k;
for ( int i = hd[x]; i && res; i = nxt[i] ){
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( val[i], res ) );
if ( k <= 0 ) d[to[i]] = 0;
res -= k; val[i] -= k; val[i ^ 1] += k;
}
}
return fl - res;
}
Correct:
int DFS( int x, int fl ){
if ( x == T ) return fl;
int res(fl), k;
for ( int i = hd[x]; i && res; i = nxt[i] ){
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( val[i], res ) );
if ( k <= 0 ) d[to[i]] = 0;
res -= k; val[i] -= k; val[i ^ 1] += k;
}
}
return fl - res;
}
结果。。。输出都是0.。。。
XI 宽搜时忘记push源点
我真的智障了
d[S] = 1; Q.push(S);
XII 忘了开long long
丢脸 看看数据范围
XIII 数组开小了
做网络流要空间何用!数组下标加个0
XIV 没看见双向边
题目看清楚 T-T