P2017 Dizzy Cows(经典拓扑排序)

本题算是一个比较经典的拓扑模板题,只添加了一个标记拓扑顺序的数组top就可以了

在加入单向边后进行拓扑排序,拓扑排序中进行top数组记录

再加入双向边时,根据拓扑排序的性质(top值表示拓扑排序的位置),任意两个点,添加的边只要是top值小的点指向top值大的点就是可以满足的(等于也可以,在我实现的代码中,等于的只有0值,即入度为零的节点)

入门小白一个,请多多指教

#include
#include
#include
#include
#include
#define int long long
using namespace std;
const int NN = 1e5 + 17, M = 1e5 + 17;//NN是节点数,M是边数
int n, cnt, deg[NN], lin[NN];//n是节点数,deg是入度

//TODO(根据题目设全局变量)
//FROM
int top[NN];
//END

struct node {
	int to, next;
}e[M];

void add(int f, int t) {
	deg[t]++;
	cnt++;
	e[cnt].to = t;
	e[cnt].next = lin[f];
	lin[f] = cnt;
}

void init() {
	cnt = 0;
	for (int i = 0; i <= n; i++)
		deg[i] = lin[i] = 0;

	//TODO(根据题目进行初始化相应的条件)
	//BEGIN
	for (int i = 0; i <= n; i++)
		top[i] = 0;
	//END
}

void bfs() {
	queue Q;
	for (int i = 1; i <= n; i++)
		if (deg[i] == 0) {
			Q.push(i);
			//TODO
			//FROM
			top[i] = cnt++;
			//END
		}
	while (!Q.empty()) {
		int now = Q.front();
		Q.pop();
		for (int i = lin[now]; i > 0; i = e[i].next) {
			deg[e[i].to]--;
			//TODO(根据题目进行操作)
			//FROM

			//END
			if (deg[e[i].to] == 0) {
				Q.push(e[i].to);
				//TODO(根据题目进行操作)
				//FROM
				top[e[i].to] = cnt++;
				//END
			}
		}
	}
}

signed main() {
	int p1, p2;
	cin >> n >> p1 >> p2;
	for (int i = 1; i <= p1; i++) {
		int x, y;
		cin >> x >> y;
		add(x, y);
	}
	bfs();
	for (int i = 1; i <= p2; i++) {
		int x, y;
		cin >> x >> y;
		if (top[x] > top[y])
			cout << y << ' ' << x << endl;
		else
			cout << x << ' ' << y << endl;
	}
	return 0;
}

你可能感兴趣的:(拓扑排序,算法)