拓扑排序就是每次取入度为零的数进行排序,所以不能有环,每次取出入度为零的数,再把与其相关的数的入度减一,若为1则入队。
同时拓扑排序也可以用于找环如果在拓扑排序中出现了环,在逐步删减入度为零的数时,
会出现没有入度为零的点,从而使排序出来的数不足n个,这样就可以判定有环。
HDU——1285
代码如下
下面的代码使用了优先队列,是因为要求排列出来的队伍要按照大小顺序排列。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 10005;
const int inf = 0x3f3f3f3f;
typedef long long ll;
vector<int>w[maxn];
int f[maxn];
int ans[maxn];
int n,m;
void tuopu()
{
priority_queue<int,vector<int>,greater<int>>q;
int k=0;
for(int i=1;i<=n;i++){
if(!f[i])
q.push(i);
}
while(!q.empty()){
int e=q.top();
q.pop();
f[e]=-1;
ans[k++]=e;
for(int i=0;i<w[e].size();i++){
f[w[e][i]]--;
if(!f[w[e][i]]){
q.push(w[e][i]);
}
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m)){
int a,b;
memset(f,0,sizeof(f));
for(int i=0;i<maxn;i++){
w[i].clear();
}
for(int i=0;i<m;i++){
scanf("%d %d",&a,&b);
f[b]++;
w[a].push_back(b);
}
tuopu();
for(int i=0;i<n;i++){
if(i==n-1)
printf("%d\n",ans[i]);
else
printf("%d ",ans[i]);
}
}
return 0;
}
//用vector实现的;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 10005;
const int inf = 0x3f3f3f3f;
typedef long long ll;
struct node
{
int y,p;
}s[maxn];
int f[maxn];
int ans[maxn];
int head[maxn];
int n,m;
int cnt=0;
void add(int a,int b)
{
s[++cnt]=node{b,head[a]};
head[a]=cnt;
}
void tuopu()
{
priority_queue<int,vector<int>,greater<int>>q;
int k=0;
for(int i=1;i<=n;i++){
if(!f[i])
q.push(i);
}
while(!q.empty()){
int e=q.top();
q.pop();
f[e]=-1;
ans[k++]=e;
for(int i=head[e];~i;i=s[i].p){
f[s[i].y]--;
if(!f[s[i].y]){
q.push(s[i].y);
}
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m)){
int a,b;
cnt=0;
memset(f,0,sizeof(f));
memset(head,-1,sizeof(head));
for(int i=0;i<m;i++){
scanf("%d %d",&a,&b);
f[b]++;
add(a,b);
}
tuopu();
for(int i=0;i<n;i++){
if(i==n-1)
printf("%d\n",ans[i]);
else
printf("%d ",ans[i]);
}
}
return 0;
}//用链式向前星实现