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;
}