需要记录每个点的出度或者入度,当出度或者入度为1时,才将这个点放到待拓展的队列中,这样保证顺序的先后性
一、模板
B3644 【模板】拓扑排序 / 家谱树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
const int N = 3e2 + 10;
vector<int> g[N];
int din[N];
int n;
void toposort(){
queue<int> q;
for(int i = 1; i <= n; i++){
if(din[i] == 0){
cout << i << ' ';
q.push(i);
}
}
while(q.size()){
int now = q.front(); q.pop();
for(auto &nex : g[now]){
din[nex]--;
if(din[nex] == 0){
cout << nex << ' ';
q.push(nex);
}
}
}
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
int x;
while(cin >> x){
if(x == 0) break;
g[i].push_back(x);
din[x]++;
}
}
toposort();
}
二、应用
1.概率问题
P4316 绿豆蛙的归宿 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
计算概率有两种方式,这里写的是从七点开始的方式
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct edge{
int v;
db w;
};
vector<edge> g[N];
int din[N];
int n, m;
db dp[N], p[N];
void toposort(){
queue<int> q;
for(int i = 1; i <= n; i++){
if(din[i] == 0){
q.push(i);
}
}
dp[1] = 0.000;
p[1] = 1.000;
while(q.size()){
int now = q.front(); q.pop();
// cout << '\n' << now << ":::\n";
// for(int i = 1; i <= n; i++){
// cout << p[i] << ' ' << dp[i] << '\n';
// }
for(auto &nex : g[now]){
dp[nex.v] += (dp[now] + nex.w * p[now]) / (db)g[now].size();
p[nex.v] += p[now] / (db)g[now].size();
din[nex.v]--;
if(din[nex.v] == 0){
q.push(nex.v);
}
}
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i++){
int u, v; db w; cin >> u >> v >> w;
g[u].push_back({v, w});
din[v]++;
}
toposort();
cout << fixed << setprecision(2) << dp[n] << '\n';
}
2.数转图论
#include<bits/stdc++.h>
using namespace std;
#define qio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
typedef long long ll;
typedef double db;
const int N = 1e5 + 10;
vector<int> g[N];
int din[N];
bool nofind(int x, int y) {
for (auto &i : g[x]) {
if (i == y) return false;
}
return true;
}
bool cmp(int x, int y){
return din[x] > din[y];
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n - 2; i++) {
int x, y, z;
cin >> x >> y >> z;
din[x]++, din[y]++, din[z]++;
if (nofind(x, y)) g[x].push_back(y);
if (nofind(x, z)) g[x].push_back(z);
if (nofind(y, z)) g[y].push_back(z);
if (nofind(y, x)) g[y].push_back(x);
if (nofind(z, x)) g[z].push_back(x);
if (nofind(z, y)) g[z].push_back(y);
}
for(int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end(), cmp);
int id = 0, mi = 1e9, la = 0;
for(int i = 1; i <= n; i++){
if(din[i] == 1){
if(id == 0)id = i;
else la = i;
}
}
queue<int> q;
q.push(id);
while(q.size()){
int x = q.front();
q.pop();
cout << x << ' ';
for(auto &i : g[x]){
din[i]--;
if(din[i] == 1){
q.push(i);
}
}
}
cout << la << '\n';
}
signed main() {
qio
int T = 1;
// cin >> T;
while (T--)solve();
}