2021-05-02
2021/5/2 18:25:36
本文主要是介绍2021-05-02,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
ALG2:拓扑排序
问题描述如下:
(详见NKU计算机上机课程辅助评测)
拓扑排序
具体实现:
(以通过全部的测试样例)
比较笨的方法,有较大的优化空间,对于输出成环的情况有较大的优化空间
#include<iostream> #include<vector> #include<stack> #include<set> #include<algorithm> using namespace std; void dfs(stack<int>& path, vector<bool>& ifVisited, vector<vector<int>>& graph, int start, bool& loop) { ifVisited[start] = true; path.push(start); //递归出口 bool end = true; for (int i = 1; i < graph.size(); i++) { if (graph[start][i] != 0) { end = false; break; } } if (end) return; //如果存在后继节点 for (int i = 1; i < graph.size(); i++) { if (graph[start][i] != 0 && !ifVisited[i]) {//后继节点没有被访问过 dfs(path, ifVisited, graph, i, loop); if (loop) break; else { path.pop(); ifVisited[i] = false; } } if (graph[start][i] != 0 && ifVisited[i]) {//后继节点被访问过,存在回路 loop = true; stack<int> st; st.push(i); while (path.top() != i) { st.push(path.top()); path.pop(); } st.push(path.top()); path = st; break; } } } int main() { //初始化 int n, m; cin >> n >> m; set<int> in_0; vector<int> ans; vector<bool> visited(n + 1, false); //表示是否访问过 vector<int> in(n + 1, 0); //存储各个节点的入度 vector<vector<int>> graph(n + 1, vector<int>(n + 1, 0)); //0表示不存在路径 for (int i = 0; i < m; i++) { int start, end; cin >> start >> end; graph[start][end] = 1; in[end]++; } //数据处理 for (int i = 1; i <= n; i++) if (in[i] == 0) in_0.insert(i); while (!in_0.empty()) { set<int>::iterator iter = in_0.begin(); int node = *iter; ans.push_back(node); visited[node] = true; for (int i = 1; i <= n; i++) if (graph[node][i]) if (--in[i] == 0 && !visited[i]) in_0.insert(i); in_0.erase(iter); } //结果输出 if (ans.size() == n) { cout << "YES" << endl; for (int i = 0; i < ans.size(); i++) { cout << ans[i]; if (i != ans.size() - 1) cout << ","; } } else {//存在成环的情况 cout << "NO" << endl; for (int i = 1; i <= n; i++) {//将所有点都遍历一遍 vector<bool> ifVisited(n + 1, false); //保存节点是否访问过 stack<int> path; //保存路径 bool loop = false; //用来储存该节点作为起始节点的起始路径是否存在回路 dfs(path, ifVisited, graph, i, loop); if (loop) { while (!path.empty()) { cout << path.top(); if (path.size() != 1) cout << ","; path.pop(); } break; } } } return 0; }
仅供复习时整理参考,用于学习交流
这篇关于2021-05-02的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Java创意资料:新手入门的创意学习指南
- 2024-11-25JAVA对接阿里云智能语音服务资料详解:新手入门指南
- 2024-11-25Java对接阿里云智能语音服务资料详解
- 2024-11-25Java对接阿里云智能语音服务资料详解
- 2024-11-25JAVA副业资料:新手入门及初级提升指南
- 2024-11-25Java副业资料:入门到实践的全面指南
- 2024-11-25Springboot应用的多环境打包项目实战
- 2024-11-25SpringBoot应用的生产发布项目实战入门教程
- 2024-11-25Viite多环境配置项目实战:新手入门教程
- 2024-11-25Vite多环境配置项目实战入门教程