给定一个有N个节点的有向图(编号为0~N-1),求其拓扑排序的最小字典序。

(P.S.简单地叙述)

 

INPUT:

第一行两个整数 N和M,表示图有N个点,M条边。
接下来M行,2个整数ui和vi,表示ui到vi有条有向边。

3 2
0 2
1 2

对于60%的数据,N ≤ 1, 000。
对于100%的数据,N ≤ 100, 000,M ≤ 1, 000, 000.

 

OUTPUT:

N个用空格隔开的整数,表示拓扑序列。

0 1 2

 

思路:

就是简单的把拓扑排序的队列变为优先队列(小根堆)。

(并且不用考虑是否重边)

cpp:

 

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<iomanip>
 8 #include<queue>
 9 #include<vector>
10 #include<cstring>
11 using namespace std;
12 const int maxn=1000010;
13 int n,m;
14 int id[maxn];
15 bool x[maxn],y[maxn];
16 int linkk[maxn],len=0;
17 priority_queue< int ,vector< int >,greater< int > >q;
18 struct node
19 {
20     int x,y,v;
21 }e[maxn];
22 
23 void init(int xx,int yy)
24 {
25     e[++len].y=linkk[xx];linkk[xx]=len;
26     e[len].x=yy;e[len].v=1;
27     id[yy]++;
28     
29 }
30 
31 void tou()
32 {
33     for(int i=0;i<n;i++)
34         if(id[i]==0) 
35         {
36             q.push(i);
37         }
38     while(!q.empty())
39     {
40         int st=linkk[q.top()];
41         cout<<q.top()<<" ";
42         q.pop();
43         for(int i=st;i;i=e[i].y)
44         {
45             int tmp=e[i].x;
46             id[tmp]--;
47             if(id[tmp]==0)
48             {
49                 q.push(tmp);
50             }
51         }
52     }
53 }
54 
55 int main()
56 {
57     /*freopen("2.in","r",stdin);
58     freopen("2.out","w",stdout);*/
59     //ios::sync_with_stdio(false);
60     cin>>n>>m;
61     for(int i=1;i<=m;i++)
62     {
63         int a,b; 
64         cin>>a>>b;
65         init(a,b);
66     }
67     tou();
68     cout<<endl;
69     return 0;
70 }
View Code