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:注意去重!


目录
相关文章
|
3月前
|
算法
Hierholzer算法dfs找欧拉回路模板
Hierholzer算法dfs找欧拉回路模板
36 0
|
7月前
|
存储 算法 决策智能
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)
48 0
|
7月前
|
算法 C++ 容器
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(上)
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(上)
27 0
|
6月前
|
算法 C++ 索引
函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜(下)
函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜(下)
24 0
|
2月前
|
算法 测试技术 C++
【广度优先搜索】【拓扑排序】【C++算法】913. 猫和老鼠
【广度优先搜索】【拓扑排序】【C++算法】913. 猫和老鼠
|
2月前
|
存储 算法 搜索推荐
C++模板与STL【常用算法】
C++模板与STL【常用算法】
|
7月前
|
算法 计算机视觉
基于方向编码的模板匹配算法matlab仿真
基于方向编码的模板匹配算法matlab仿真
|
4月前
|
存储 人工智能 算法
【算法总结】拓扑排序
【算法总结】拓扑排序
30 0
|
4月前
|
算法
拓扑排序【学习算法】
拓扑排序【学习算法】
32 0
|
4月前
|
算法 搜索推荐 Python
Python算法——树的拓扑排序
Python算法——树的拓扑排序
70 0

热门文章

最新文章