乐逍遥xwl

导航

拓扑排序

先建图,根据边计算所有顶点的入度,然后扫一遍将入度为0的顶点入队,

同时,该顶点指向的顶点入度减一,在队列中重复此操作,

直到所有点都被分离,如果顶点没有全部分离出来,

那么说明有环,不存在拓扑序,无解,详情见代码。

 

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<map>
 7 #include<set>
 8 #include<vector>
 9 #include<queue>
10 #include<list>
11 #include<stack>
12 //#include<unordered_map>
13 using namespace std;
14 #define ll long long 
15 const int mod=1e9+7;
16 const long long int inf=1e18+7;
17 
18 const int maxn=1e5+10;
19 vector<int>edge[maxn];
20 int in[maxn];
21 int n,m;
22 void toupu()
23 {
24     queue<int>q;
25     for(int i=1;i<=n;i++)
26     {
27         if(in[i]==0)//找到入度为0顶点入队 
28         {
29             q.push(i);
30         }
31     }
32     vector<int>ans;//存拓扑序 
33     while(!q.empty())
34     {
35         int now=q.front();//取出队首 
36         q.pop();
37         ans.push_back(now);
38         for(int i=0;i<edge[now].size();i++)
39         {                        //去掉这个点涉及的边 
40             in[edge[now][i]]--;//相连边的另一个顶点入度减一 
41             if(in[edge[now][i]]==0)//该点入度减为0 
42             {
43                 q.push(edge[now][i]);//入队 
44             }
45         }
46     }
47     if(ans.size()!=n)//无n个顶点 
48     {
49         cout<<-1<<endl;//无解 
50         return ;
51     }
52     cout<<ans[0]; 
53     for(int i=1;i<ans.size();i++)//输出拓扑序 
54         cout<<" "<<ans[i];
55     cout<<endl;    
56 }
57 
58 int main()
59 {
60     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
61     cin>>n>>m;//n个点,m条有向边 
62     for(int i=0;i<=n;i++)//初始化图 
63         edge[i].clear();
64     memset(in,0,sizeof(in));//初始化入度 
65     int x,y;
66     for(int i=0;i<m;i++)
67     {
68         cin>>x>>y;
69         edge[x].push_back(y);//建图 
70         in[y]++;//入度加一 
71     }
72     toupu();//求拓扑序 
73     return 0;
74 }
75 /*76 6 8
77 1 2
78 1 3
79 1 4
80 3 2
81 3 5
82 4 5
83 6 4
84 6 5
85 
86 1 6 3 4 2 5
87 */

 

posted on 2019-08-22 21:25  乐逍遥xwl  阅读(129)  评论(0编辑  收藏  举报