Dizzy Cows(拓扑排序经典)
本题算是一个比较经典的拓扑模板题,只添加了一个标记拓扑顺序的数组top就可以了
在加入单向边后进行拓扑排序,拓扑排序中进行top数组记录
再加入双向边时,根据拓扑排序的性质,任意两个点,添加的边只要是top值小的点指向top值大的点就是可以满足的(等于也可以,在我实现的代码中,等于的只有0值,即入度为零的节点)
PS:本题数据似乎有点弱,题目节点值和边数只开1e4也过了,题目里讲到的是1e5,洛谷P2017的数据强一些,应该到了1e5级别
入门小白一个,请多多指教
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> #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<int> 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; }