图论 拓扑排序

拓扑排序

就系按图中节点度的个数来排序,入度少优先

存图时用数组统计每个节点的入度,用队列/数组模拟,入度为0的先入队,遍历相邻节点,入度--,入度为0的再入队,同时存点,直至队列为空

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<string>
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int, int> p;
typedef long long ll;
#define fi first
#define se second
#define MAXN 100000+5
#define NIL -1
#define me(x) memset(x, -1, sizeof(x))
#define mem(x) memset(x, 0, sizeof(x))
struct node
{
    int next, to; //edge[i].to 存 第i条边 的终点 .next存与边i同起点的前一条边
}edge[MAXN];
int head[MAXN]; //head[i] i为有边节点 head存该节点 边 的最大编号 存的是边
int cnt;
int indegree[MAXN];
void add(int u, int v)
{
    edge[cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
int main()
{
    int i, j, k, l;
    int n, m;
    int u, v;
    while(cin>>n>>m && (n||m)) //n节点个数 m边数 一个节点可能有多条边
    {
        cnt=0;
        me(head);
        mem(indegree);
        for(i=0; i<m; i++)
            cin>>u>>v, indegree[v]++, add(u, v);
        int que[MAXN];//存节点
        int iq=0;
        for(i=1; i<=n; i++)
            if(!indegree[i])
            que[iq++]=i;
        //int x[MAXN]; j=0;
        for(i=0; i<iq; i++)
            for(k=head[que[i]]; ~k; k=edge[k].next)   //注意 这里逆序
             //x[j++]=k;
             //for(k=j-1; k>=0; k--)
            {
                indegree[edge[k].to]--;//顺序输出的话 这三行k改为x[k]
                if(!indegree[edge[k].to])
                    que[iq++]=edge[k].to;
            }
        if(iq<n) {cout<<"There is a loop"<<endl;continue;}
        for(i=0; i<iq; i++)
            cout<<que[i]<<' ';
        cout<<endl;
    }
    return 0;
}

 HDU 4857 逃生

一般拓扑排序都按字典序最小输出,这里要求数字最小先输出

先反向建图,改用优先队列,最后逆序输出就好了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
#define mem(x) memset(x, 0, sizeof(x))
#define me(x) memset(x, -1, sizeof(x))
#define lowbit(x) x&-x
const ll MOD = 1e18;
const int N = 2e5 + 5;
struct node
{
    int to, next;
}e[N];
int id, head[N], dep[N];
void add(int u, int v)
{
    e[id].to=v;
    e[id].next=head[u];
    head[u]=id++;
}
struct cmp
{
    bool operator() (const int &a, const int &b) const
    {
        return a<b;
    }
};
int main()
{
    int  i, j, k;
    int n, m, t;
    int u, v;
    int a, b;
    scanf("%d", &t);
    while(t--)
    {
        mem(dep); id=0; me(head);
        scanf("%d%d", &n, &m);
        for(i=0; i<m; i++)
            scanf("%d%d", &u, &v), add(v,u), dep[u]++;
        priority_queue< int, vector<int>, cmp> q;
        for(i=1; i<=n; i++)
            if(!dep[i]) q.push(i);
        int b[N], l=0;
        while(q.size())
        {
            k=q.top();
            b[l++]=k;
            q.pop();
            for(i=head[k]; ~i; i=e[i].next)
            {
                if(dep[e[i].to]) dep[e[i].to]--;
                if(!dep[e[i].to]) q.push(e[i].to);
            }
        }
        for(i=l-1; i>=1; i--)
            printf("%d ", b[i]);
        printf("%d\n", b[i]);
    }
    return 0;
}
View Code

 

posted @ 2019-08-01 15:50  op-z  阅读(116)  评论(0编辑  收藏  举报