什么是拓扑序列:
(引用blog拓扑序列(拓扑排序)-CSDN博客)
注:
1.拓扑序列只针对有向图来说
2.不是所有图都有拓扑序列
3.有向无环图一定存在拓扑序列,称为拓扑图
模版题目
思路:
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
思路:
套模版即可
代码如下:
#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
思路:
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;
}