ACM模板——拓扑排序算法

简介: ACM模板——拓扑排序算法

注释版(邻接表_版本):

1.#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
const int MAXV=1000;
// 边结点
struct ENode
{
    int adjvex; // 邻接点:弧头顶点(下标)
    int weight; // 权值
    ENode *next; // 链域,下一个邻接点
};
// 顶点结点
typedef struct VNode
{
    int in;        // 入度
    int data;      // 顶点信息
    ENode *firstE; // 边表头指针
}AdjList[MAXV];
// 邻接表
typedef struct gAList
{
    AdjList adjList;
    int numV,numE; // 顶点数  边数
}*GAList;
int TopoSort(GAList GAL) // 拓扑排序
{
    ENode *e;
    int top=0; // 用于sk栈指针下标
    int cnt=0; // 统计输出顶点的个数
    int *sk; // 建栈,存储入度为0的顶点
    sk=(int *)malloc(GAL->numV*sizeof(int));
    for(int i=0;i<GAL->numV;i++)
        if(GAL->adjList[i].in==0)
            sk[++top]=i; // 将入度为0的顶点入栈;++top 从1开始,为下文 while(top!=0) 做准备
    while(top!=0)
    {
        int gettop=sk[top--]; // 出栈
        printf("%d -> ",GAL->adjList[gettop].data);
        cnt++; // 统计输出顶点数
        for(e=GAL->adjList[gettop].firstE; e; e=e->next) // 对此顶点弧表遍历
        {
            int k=e->adjvex;
            if(!(--GAL->adjList[k].in)) // 将k号顶点邻接点的入度-1
                sk[++top]=k; // 若为0则入栈,方便下次循环输出
        }
    }
    if(cnt<GAL->numV) // 若 cnt 小于顶点数,则存在环
        return 0;
    else
        return 1;
}

简化版(邻接表_版本):

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
const int MAXV=1000;
struct ENode
{
    int adjvex; 
    int weight; 
    ENode *next; 
};
typedef struct VNode
{
    int in;        
    int data;      
    ENode *firstE; 
}AdjList[MAXV];
typedef struct gAList
{
    AdjList adjList;
    int numV,numE;
}*GAList;
int TopoSort(GAList GAL)
{
    ENode *e;
    int top=0; 
    int cnt=0; 
    int *sk; 
    sk=(int *)malloc(GAL->numV*sizeof(int));
    for(int i=0;i<GAL->numV;i++)
        if(GAL->adjList[i].in==0)
            sk[++top]=i; 
    while(top!=0)
    {
        int gettop=sk[top--]; 
        printf("%d -> ",GAL->adjList[gettop].data);
        cnt++; 
        for(e=GAL->adjList[gettop].firstE; e; e=e->next) 
        {
            int k=e->adjvex;
            if(!(--GAL->adjList[k].in)) 
                sk[++top]=k; 
        }
    }
    if(cnt<GAL->numV) 
        return 0;
    else
        return 1;
}

释版(邻接矩阵_版本):

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int MAXV=1010;
// 邻接矩阵
int mp[MAXV][MAXV]; // 边结点
int in[MAXV]; // 入度
int n,m;
void TopoSort()
{
    int top=-1; // 回路标记
    for(int i=0;i<n;i++)
    {
        if(in[i]==0)
        {
            in[i]=top; // 类似next[]存储
            top=i; // FILO思想
        }
    }
    for(int i=0;i<n;i++)
    {
        if(top==-1) // 存在回路
        {
            return ;
        }
        else
        {
            int j=top;
            top=in[top]; // 每次都是 -1,做标记,看接下来for_k是否有符合的新零度点。若没有,存在回路
            printf("%d ",j); // 输出结果
            for(int k=0;k<n;k++)
            {
                if(mp[j][k] && --in[k]==0) // 将j号顶点邻接点k的入度-1
                {
                    in[k]=top; // 同上
                    top=k; // 同上
                }
            }
        }
    }
}

简化版(邻接矩阵_版本):

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int MAXV=1010;
int mp[MAXV][MAXV];
int in[MAXV];
int n,m;
void TopoSort()
{
    int top=-1;
    for(int i=0;i<n;i++)
    {
        if(in[i]==0)
        {
            in[i]=top;
            top=i;
        }
    }
    for(int i=0;i<n;i++)
    {
        if(top==-1)
        {
            return ;
        }
        else
        {
            int j=top;
            top=in[top];
            printf("%d ",j);
            for(int k=0;k<n;k++)
            {
                if(mp[j][k] && --in[k]==0)
                {
                    in[k]=top;
                    top=k;
                }
            }
        }
    }
}

简化版(邻接矩阵_优先队列_版本):

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a)
#define ssclr(ss) ss.clear(), ss.str("")
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;
const int maxn=520;
int n;
int g[maxn][maxn], in[maxn];
priority_queue<int,vector<int>,greater<int>> pq;
vector<int> vec;
void init()
{
    mem(g,0), mem(in,0);
    while(!pq.empty()) pq.pop();
    vec.clear();
}
void topo()
{
    for(int i=1;i<=n;i++)
        if(in[i]==0) pq.push(i);
    int tp;
    while(!pq.empty())
    {
        tp=pq.top(); pq.pop();
        vec.push_back(tp);
        for(int i=1;i<=n;i++)
            if(g[tp][i] && --in[i]==0) pq.push(i);
    }
}
int main()
{
    int m,u,v;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            if(g[u][v]==0 && u!=v)
            {
                g[u][v]=1;
                in[v]++;
            }
        }
        topo();
        if(vec.size()!=n) puts("-1");
        else
        {
            for(int i=0;i<vec.size();i++)
                printf("%d%c",vec[i],i==vec.size()-1?'\n':' ');
        }
    }
    return 0;
}

Ps:注意去重!


目录
相关文章
|
6月前
|
人工智能 算法 BI
【优选算法专栏】专题十八:BFS解决拓扑排序(一)
【优选算法专栏】专题十八:BFS解决拓扑排序(一)
47 0
|
6月前
|
算法
【优选算法专栏】专题十八:BFS解决拓扑排序--前言
【优选算法专栏】专题十八:BFS解决拓扑排序--前言
51 1
|
3月前
|
算法
【算法】前缀和——二维前缀和模板题
【算法】前缀和——二维前缀和模板题
|
5月前
|
算法 Java 数据处理
Java算法模板 数据流快读
Java算法模板 数据流快读
36 2
|
4月前
|
设计模式 JavaScript 算法
vue2 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法
vue2 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法
161 0
|
5月前
|
存储 算法
算法BFS经典例题(迷宫,多源BFS,BFS解决拓扑排序,FloodFill算法)
算法BFS经典例题(迷宫,多源BFS,BFS解决拓扑排序,FloodFill算法)
|
5月前
|
算法 Java 调度
Java数据结构与算法:拓扑排序
Java数据结构与算法:拓扑排序
|
5月前
|
算法 前端开发 安全
C++算法模板
C++算法模板
31 0
|
5月前
|
算法 C语言
数据结构与算法——拓扑排序(引例、拓扑排序、伪代码、代码、关键路径问题)
数据结构与算法——拓扑排序(引例、拓扑排序、伪代码、代码、关键路径问题)
50 0
|
6月前
|
算法 项目管理 数据中心
【数据结构】拓扑网络(AOE算法举例+源码)
【数据结构】拓扑网络(AOE算法举例+源码)
【数据结构】拓扑网络(AOE算法举例+源码)