共42道题,当前是第24

初赛真题

每头奶牛都不想成为被新型病毒感染的奶牛。被所有奶牛接触的奶牛就是一头被感染的奶牛。因为奶牛喜欢偷偷摸摸地行动,所有接触是单向的,所有奶牛都与自己接触。奶牛之间的接触是可以传递的——如果 $A$ 接触过 $B$ ,$B$ 接触过 $C$ ,那么 $A$ 也接触过 $C$ 。牛栏里共有 $N$ 头奶牛,给定一些奶牛之间的接触关系,请你算出有多少头奶牛不幸被感染。 输入的第一行是两个用空格分开的整数 $N$ 和 $M$ 。接下来 $M$ 行每行两个用空格分开的整数 $A$ 和 $B$ ,表示 $A$ 接触过 $B$ 。输出被感染的奶牛的数量。

提示:考虑将接触关系建图,强连通缩点,然后进行接下来的操作。

#include<bits/stdc++.h>
using namespace std;
struct edge {
	int v, next;
} p[50001];
int front[10001], M;
void Add(int u, int v) {
	++M;
	p[M].v = v;
	___(1)___;
	front[u] = M;
}
int dfn[10001], low[10001], N, s;
stack <int> zhan;
int which[10001];
int Out[10001], id, large[10001];
int n, m;

int dfs(int x) {
	++N;
	dfn[x] = low[x] = N;
	zhan.push(x);
	for (int i = front[x]; i; i = p[i].next) {
		if (___(2)___) {
			dfs(p[i].v);
			___(3)___;
		} else
			low[x] = min(low[x], dfn[p[i].v]);
	}
	if (dfn[x] == low[x]) {
		++s;
		int S = 0;
		int v;
		do {
			v = zhan.top();
			zhan.pop();
			___(4)___;
			++S;
		} while (x != v);
		Large[s] = S;
	}
}

int main() {
	int i, j;
	scanf("%d%d", & n, & m);
	for (i = 1; i <= m; ++i) {
		int x, y;
		scanf("%d%d", &x, &y);
		Add(x, y);
	}
	for (i = 1; i <= n; ++i)
		if (dfn[i] == 0) dfs(i);
	for (i = 1; i <= n; ++i)
		for (j = front[i]; j; j = p[j].next)
			if (which[p[j].v] != which[i])
				___(5)___;
	for (i = 1; i <= s; ++i)
		if (Out[i] == 0) {
			if (id != 0) {
				printf("%d\n", 0);
				return 0;
			}
			id = i;
		}
	printf("%d\n", large[id]);
	return 0;
}

1. C。
2. A。
3. D。
4. B。
5. A。

Tarjan 缩点后,图为有向无环图。如果此时图中存在多个出度为 $0$ 的点,则没有被感染的奶牛,否则出度为 $0$ 的点为被感染的奶牛,输出该点内原本点的数量。

Question

1. (1) 处填入的代码是( )。

2. (2) 处填入的代码是( )。

3. (3) 处填入的代码是( )。

4. (4) 处填入的代码是( )。

5. (5) 处填入的代码是( )。

陈伦制作 版权所无 粤ICP备16127491号-1