热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

判断给定图是否存在合法拓扑序列(拓扑排序及其优化)

数据结构实验之图论十:判断给定图是否存在合法拓扑序列


数据结构实验之图论十:判断给定图是否存在合法拓扑序列
Description
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。

Input
输入包含多组,每组格式如下。

第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)

后面m行每行两个整数a b,表示从a到b有一条有向边。

Output
若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。

Sample
Input
1 0
2 2
1 2
2 1
Output
YES
NO

每次找一个入度为0的节点,删除该节点,如果找不到,则说明不存在合法拓扑序列,有环存在。
我们可以通过队列来存在入度为零的节点,以此来优化

普通暴力找入度为0的节点代码:

#include
using namespace std;
int s[12];
int ma[12][12];
int vis[12];
int u, v, n, m, i, j, k;
int main()
{
ios::sync_with_stdio(false);
while (cin >> n >> m)
{
memset(s, 0, sizeof(s));
memset(ma, 0, sizeof(ma));
memset(vis, 0, sizeof(vis));
for (int i = 0; i < m; i++)
{
cin >> u >> v;
ma[u][v] = 1;
s[v]++;
}
for (k = 0; k < n; k++)
{
int flag = 1;
for (i = 1; i <= n; i++)
{
if (s[i] == 0 && vis[i] == 0)
{
vis[i] = 1;
flag = 0;
for (j = 1; j <= n; j++)
{
if (ma[i][j]) {
s[j]--;
}
}
break;
}
}
if (flag) break;
}
if (k < n)
cout << "NO\n";
else
cout << "YES\n";
}
}

利用队列代码:

#include
using namespace std;
int s[12];
int ma[12][12];
int u, v, n, m, i, k;
int main() {
ios::sync_with_stdio(false);
while (cin >> n >> m) {
memset(s, 0, sizeof(s));
memset(ma, 0, sizeof(ma));
queue<int> q;
k = 0;
for (int i = 0; i < m; i++) {
cin >> u >> v;
ma[u][v] = 1;
s[v]++;
}
for (int i = 1; i <= n; i++) {
if (!s[i]) q.push(i);
}
while (!q.empty()) {
int t = q.front();
q.pop();
k++;
for (i = 1; i <= n; i++) {
if (ma[u][i]) {
s[i]--;
if (!s[i]) q.push(i);
}
}
}
if (k == n)
cout << "YES\n";
else
cout << "NO\n";
}
}

链式前向星存图代码

#include
using namespace std;
int s[12];
int h[12];
int cnt;
struct node {
int v, next;
} a[12];
void add(int u, int v) {
a[++cnt].v = v;
a[cnt].next = h[u];
h[u] = cnt;
}
int u, v, n, m, i, k;
int main() {
ios::sync_with_stdio(false);
while (cin >> n >> m) {
cnt = 0;
memset(h, 0, sizeof(h));
memset(s, 0, sizeof(s));
queue<int> q;
k = 0;
for (int i = 0; i < m; i++) {
cin >> u >> v;
add(u, v);
s[v]++;
}
for (int i = 1; i <= n; i++) {
if (!s[i]) q.push(i);
}
while (!q.empty()) {
int t = q.front();
q.pop();
k++;
for (i = h[t]; i; i = a[i].next) {
s[a[i].v]--;
if (!s[a[i].v]) q.push(i);
}
}
if (k == n)
cout << "YES\n";
else
cout << "NO\n";
}
}


推荐阅读
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • 本文详细介绍了C语言中链表的两种动态创建方法——头插法和尾插法,包括具体的实现代码和运行示例。通过这些内容,读者可以更好地理解和掌握链表的基本操作。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 本题旨在通过给定的评级信息,利用拓扑排序和并查集算法来确定全球 Tetris 高手排行榜。题目要求判断是否可以根据提供的信息生成一个明确的排名表,或者是否存在冲突或信息不足的情况。 ... [详细]
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
author-avatar
是非涩味_943
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有