图论基础——拓扑排序

拓扑排序就是每次取入度为零的数进行排序,所以不能有环,每次取出入度为零的数,再把与其相关的数的入度减一,若为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;
}//用链式向前星实现
发布了35 篇原创文章 · 获赞 25 · 访问量 837

猜你喜欢

转载自blog.csdn.net/qq_43816599/article/details/96017062