给任务排序(uva 10305)

来源:互联网 发布:java并发框架有哪些 编辑:程序博客网 时间:2024/05/18 03:41

John has n tasks to do. Unfortunately, thetasks are not independent and the execution of one task is only possible ifother tasks have already been executed.

 

Input

The input will consist of several instancesof the problem. Each instance begins with a line containing two integers, 1 ≤ n≤ 100 and m. n is the number of tasks (numbered from 1 to n) and m is thenumber of direct precedence relations between tasks. After this, there will bem lines with two integers i and j, representing the fact that task i must beexecuted before task j. An instance with n = m = 0 will finish the input.

 

Output For each instance, print a line withn integers representing the tasks in a possible order of execution.

 

Sample Input

5 4 1 2 2 3 1 3 1 5 0 0

 

Sample Output

1 4 2 5 3

 

题意

给定一个全为大写字母的序列,(一个大写字母代表树的一个结点),求出有多少颗不同的树满足前序遍历的序列恰好为所给的序列?

 

思路

裸的拓扑排序问题,可以用数据结构书上讲的那种方法:选择一个0入度的顶点,删除它的所有有向边,再在剩余的结点中选择另一个0入度顶点,重复这个过程,选择顶点的顺序就是拓扑排序所得的序列。这里有一个更为简便的方法,仅仅需要dfs即可实现,和普通的dfs有所不同的是访问数组有三个值。used[v]==0表示顶点v没有被访问过,used[v]==1表示v的所有子孙和它本身都已经被访问过,used[v]==-1表示v的子孙正在被访问,即以v为根结点的dfs正在执行。

这样一来,即可判断有向图中是否有环,还能在没有环时求出拓扑序列。

坑点:判断m和n同时为0的条件容易想错。是(m||n)而不是(m&&n),画个真值表就明白了。


代码

#include<bits/stdc++.h>using namespace std;const int maxn = 150;int m, n;int from, to;vector<int> G[maxn];vector<int> ans;int used[maxn];void init() {ans.clear();memset(used, 0, sizeof(used));for (int i = 0; i < maxn; i++) G[i].clear();}bool dfs(int v) {used[v] = -1;for (int i = 0; i < G[v].size(); i++) {int u = G[v][i];if (-1 == used[u]) return false;if (0 == used[u] && !dfs(u)) return false;}used[v] = 1;ans.push_back(v);return true;}bool toposort() {for (int i = 1; i <= n; i++) {if (!used[i]) if (!dfs(i)) return false;}return true;}int main() {while (scanf("%d%d", &n, &m) == 2 && (n || m)) {init();for (int i = 0; i < m; i++) {scanf("%d%d", &from, &to);G[from].push_back(to);}if (!toposort()) continue;reverse(ans.begin(), ans.end());for (int i = 0; i < ans.size(); i++) {printf("%d%c", ans[i], i + 1 == ans.size() ? '\n' : ' ');}}return 0;}


原创粉丝点击