本博客已停止更新!请移步至louhc.github.io

「错题集」网络流

这里贴些曾经写网络流时犯过的沙雕错误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

posted @ 2018-12-15 15:43  louhc  阅读(291)  评论(1编辑  收藏  举报