Loading

拓扑排序(基于dfs+基于队列)

经典问题-Ordering Tasks

dfs函数的返回值表示是否成环,若存在有向环,则不存在拓扑排序。不包含有向环的有向图称为有向无环图(DAG)

可以借助DFS完成拓扑排序,在访问完一个结点时把他加入当前拓扑序的首部。

举个栗子:比如一个(1,2),(1,3),(2,3)的有向无环图,就先搜索1,再递归搜索2,再搜索3,3没有出度了,于是放进拓扑序尾=,再回到2,2除3外没有出度,再放入拓扑序,再回到1,1除2,3没有出度,放入拓扑序

 1 #include <algorithm>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <cstdlib>
 7 #include <set>
 8 #include <vector>
 9 #include <cctype>
10 #include <iomanip>
11 #include <sstream>
12 #include <climits>
13 #include <queue>
14 #include <stack>
15 using namespace std;
16 typedef long long ll;
17 #define INF 0X3f3f3f3f
18 const ll MAXN = 1e3 + 7;
19 const ll MOD = 1e9 + 7;
20 int mp[MAXN][MAXN];
21 int vis[MAXN];
22 int topo[MAXN], t;//topo数组存放最后拓扑排序结果
23 int n,k,m;
24 bool dfs(int u)//判环
25 {
26     vis[u] = -1; //访问标志
27     for(int i=1;i<=n;i++)
28     {
29         if(mp[u][i])
30         {
31             if(vis[i]==-1) return false;//存在有向环,退出
32             if(!vis[i]&&!dfs(i)) return false;
33         }
34     }
35     topo[--k]=u;
36     vis[u]=1;
37     return true;
38 }
39 bool toposort()
40 {
41     memset(vis,0,sizeof(vis));
42     k=n;
43     for(int i=1;i<=n;i++)
44          if(!vis[i]&&!dfs(i)) return false;
45     return true;
46 }
47 void print()
48 {
49     for(int i=0;i<n;i++)
50     {
51         if(i) cout<<' ';
52         cout<<topo[i];
53     }
54     cout<<endl;
55     return ;
56 }
57 int main()
58 {
59     ios::sync_with_stdio(false);
60     while (cin >> n >> m&&(n|m))
61     {
62         memset(mp,0,sizeof(mp));
63         for (int i = 0; i < m; i++)
64         {
65             int a,b;
66             cin>>a>>b;
67             mp[a][b]=1;
68         }
69         if(toposort())
70         print();
71         else
72         cout<<"sorry to say there is no DAG"<<endl;//跟题目并没有关系...
73     }
74     return 0;
75 }
View Code

 

 加个队列写法..

 1 #include <algorithm>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <cstdlib>
 7 #include <set>
 8 #include <vector>
 9 #include <cctype>
10 #include <iomanip>
11 #include <sstream>
12 #include <climits>
13 #include <queue>
14 #include <stack>
15 using namespace std;
16 typedef long long ll;
17 #define INF 0X3f3f3f3f
18 const ll MAXN = 1e3 + 7;
19 const ll MOD = 1e9 + 7;
20 int n, m;
21 int degree[MAXN][MAXN];
22 int indegree[MAXN];
23 int topo[MAXN];
24 void toposort()
25 {
26     int cnt = 0;
27     queue<int> que;
28     for (int i = 1; i <= n; i++)
29         if (!indegree[i])
30             que.push(i);
31     int cur;
32     while (!que.empty())
33     {
34         cur = que.front();
35         que.pop();
36         topo[cnt++] = cur;
37         for (int i = 1; i <= n; i++)
38         {
39             if (degree[cur][i])
40             {
41                 indegree[i]--;
42                 if (!indegree[i])
43                     que.push(i);
44             }
45         }
46     }
47     return;
48 }
49 void print()
50 {
51     for (int i = 0; i < n; i++)
52     {
53         if (i)
54             cout << ' ';
55         cout << topo[i];
56     }
57     cout << endl;
58     return;
59 }
60 int main()
61 {
62     ios::sync_with_stdio(false);
63     while (cin >> n >> m && (n | m))
64     {
65         memset(degree, 0, sizeof(degree));
66         memset(indegree, 0, sizeof(indegree));
67         while (m--)
68         {
69             int a, b;
70             cin >> a >> b;
71             if (!degree[a][b])
72             {
73                 degree[a][b] = 1;
74                 indegree[b]++;
75             }//处理重边
76         }
77         toposort();
78         print();
79     }
80     return 0;
81 }
View Code

 

posted @ 2019-02-22 16:38  GrayKido  阅读(621)  评论(0编辑  收藏  举报