题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4010
要是考场上想不出,但是还是有一个分治的做法的嘛
做法就是反向连边,然后再反向输出字典序最大的拓扑序。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 #include<queue> 9 using namespace std; 10 #define maxn 1001000 11 #define llg long long 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 llg n,m,du[maxn],bj[maxn],dl[maxn],tail,T; 14 vector<llg>a[maxn]; 15 16 struct node 17 { 18 llg po,du; 19 bool operator <(const node&a)const 20 { 21 if (a.du==du) return a.po>po; 22 else return a.du<du; 23 } 24 }; 25 26 priority_queue<node>q; 27 28 void init() 29 { 30 for (llg i=1;i<=n;i++) a[i].clear(),du[i]=0; 31 cin>>n>>m; 32 for (llg i=1;i<=m;i++) 33 { 34 llg x,y; 35 scanf("%lld%lld",&x,&y); 36 a[y].push_back(x); 37 du[x]++; 38 } 39 while (!q.empty()) q.pop(); 40 for (llg i=1;i<=n;i++) 41 { 42 node e; 43 e.po=i; 44 e.du=du[i]; 45 q.push(e); 46 } 47 } 48 49 bool work() 50 { 51 for (llg i=1;i<=n;i++) bj[i]=0; 52 tail=0; 53 while (!q.empty()) 54 { 55 node w=q.top(); 56 q.pop(); 57 if (bj[w.po]) continue; 58 bj[w.po]=1; 59 if (w.du!=0) return 0; 60 dl[++tail]=w.po; 61 llg x=w.po; 62 llg W=a[x].size(); 63 for (llg i=0;i<W;i++) 64 { 65 llg v=a[x][i]; 66 node e; 67 e.po=v; du[v]--; e.du=du[v]; 68 q.push(e); 69 } 70 } 71 return 1; 72 } 73 74 int main() 75 { 76 yyj("a"); 77 cin>>T; 78 while (T--) 79 { 80 init(); 81 if (!work()) puts("Impossible!"); 82 else 83 { 84 for (llg i=tail;i>=1;i--) printf("%lld ",dl[i]); 85 printf(" "); 86 } 87 } 88 return 0; 89 }