什么是拓扑序列:
若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A中都出现在 y 之前,则称 A是该图的一个拓扑序列。
(引用blog拓扑序列(拓扑排序)-CSDN博客)
注:
1.拓扑序列只针对有向图来说
2.不是所有图都有拓扑序列
3.有向无环图一定存在拓扑序列,称为拓扑图
模版题目
活动 - AcWing
思路:
1.将所有入度为0的点入队
2.进行bfs,每次取队头,枚举所有出边
代码如下:
#include<bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;int n, m;int e[N], ne[N], h[N], idx;int d[N];vector<int> res;void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void topsort()
{queue<int> q;for(int i = 1;i <= n; i++){if(!d[i]){q.push(i);res.push_back(i);}}while (!q.empty()){auto t = q.front();q.pop();for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (!--d[j]){q.push(j);res.push_back(j);}}}if (res.size() == n){for (auto x : res){cout << x << " ";}}else cout << "-1" << endl;
}
int main()
{memset(h, -1, sizeof(h));cin >> n >> m;while (m--){int a, b;cin >> a >> b;add(a, b);d[b]++;}topsort();return 0;
}
例题1
活动 - AcWing
思路:
套模版即可
代码如下:
#include<bits/stdc++.h>using namespace std;const int N = 210;int h[N],ne[N],e[N],idx,d[N];int n;vector<int> res;void tp()
{queue<int> q;for(int i = 1;i <= n; i++){if(!d[i]){q.push(i);res.push_back(i);}}while(!q.empty()){auto t = q.front();q.pop();for(int i = h[t]; i!= -1;i=ne[i]){int j = e[i];if(!--d[j]){q.push(j);res.push_back(j);}}}for(auto x : res)cout<<x<<" ";}void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}int main()
{memset(h,-1,sizeof(h));cin>>n;for(int i = 1; i<=n ;i++){int x;while(cin>>x,x){d[x]++;add(i,x);}}tp();return 0;
}
例题2
活动 - AcWing
思路:
1.套版子
2.注意删边时,奖金比上一个人val加1即可
代码如下:
#include <bits/stdc++.h>using namespace std;const int N = 10010, M = 20010;int n, m;
int h[N], e[M], ne[M], idx;
int in[N];
vector<int> L;void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void topo_sort() {queue<pair<int, int>> q;for (int i = 1; i <= n; i++)if (!in[i]) q.push({ i,100 });while (!q.empty()) {auto t = q.front();q.pop();int pos = t.first, val = t.second;L.push_back(val);for (int i = h[pos]; ~i; i = ne[i]) {int j = e[i];if (!--in[j]) q.push({j,val + 1 }); // 多一元}}
}int main() {memset(h, -1, sizeof h);cin >> n >> m;while (m--) {int x, y;cin >> x >> y;add(y, x), in[x]++;}topo_sort();if (L.size() == n) cout << accumulate(L.begin(), L.end(), 0) << "\n";else cout << "Poor Xed\n";return 0;
}