zoukankan      html  css  js  c++  java
  • 拓扑排序(基于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
  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/graytido/p/10419230.html
Copyright © 2011-2022 走看看