栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

acwing算法基础课:拓扑排序

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

acwing算法基础课:拓扑排序

拓扑排序模板

有向无环图才有拓扑序列,并且拓扑序不一定唯一

时间复杂度 O(n+m), n 表示点数,m表示边数

bool topsort()
{
    int hh = 0, tt = -1;

    // d[i] 存储点i的入度
    for (int i = 1; i <= n; i ++ )
        if (!d[i])
            q[ ++ tt] = i;

    while (hh <= tt)
    {
        int t = q[hh ++ ];

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (-- d[j] == 0)
                q[ ++ tt] = j;
        }
    }

    // 如果所有点都入队了,说明存在拓扑序列;否则不存在拓扑序列。
    return tt == n - 1;
}
例题

给定一个n个点m条边的有向图,图中可能存在重边和自环。
请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。
若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

#include 
#include 

using namespace std;

const int N = 100010;

int n, m;
int h[N], e[N], ne[N], idx;
int q[N], d[N];

void add(int a, int b)
{
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx++;
}

bool topsort()
{
	int tt = -1, hh = 0;
	
	for(int i = 1; i <= n; i++)
		if(!d[i])
			q[++tt] = i;
	
	while(hh <= tt)
	{
		int t = q[hh++];
		for(int i = h[t]; i != -1; i = ne[i])
		{
			int j = e[i];
			d[j]--;
			if(!d[j]) q[++tt] = j;
		}
	}
	
	return tt == n - 1;
}

int main()
{
	cin >> n >> m;
	
	memset(h, -1, sizeof(h));
	
	for(int i = 0; i < n; i++)
	{
		int a, b;
		cin >> a >> b;
		add(a, b);
		d[b]++;
	}
	
	if(topsort())
	{
		for(int i = 0; i < n; i++)
			cout << q[i] << ' ';
		cout << endl;
	}
	else cout << "-1" << endl;
	
	return 0;
}
测试样例
输入样例:
3 3
1 2
2 3
1 3
输出样例:
1 2 3
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/330498.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号