codeforces 825E - Minimal Labels
http://codeforces.com/contest/825/problem/E
题意:给你一个 n 个点的拓扑图,给每个点进行标记。
标记的值为 1 到 n ,每个值只能出现一次;
如果点 x 有一条指向 y 的边, x 被标记的值应该小于 y 的值;
标记的数组应该字典序最小。
其实就是 拓扑排序 ,最开始我做的时候先删除入度为0的点,优先取小的从小到大开始标记。一直WA;
题解却是从出度为 0 的点开始删,优先取大的从大到小开始标记。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #include<set> 8 using namespace std; 9 const int MAXN = 100010; 10 int ans[MAXN]; 11 set<int> out[MAXN]; 12 set<int> in[MAXN]; 13 priority_queue<int> que; 14 //ios::sync_with_stdio(false); 15 int main (void) 16 { 17 int n, m; 18 cin >> n >> m; 19 while( m-- ) 20 { 21 int v, u; 22 cin >> v >> u; 23 out[v].insert(u); 24 in[u].insert(v); 25 } 26 for(int i = 1; i <= n; i++) 27 { 28 if( !out[i].size() ) 29 { 30 que.push(i); 31 } 32 } 33 int id = n; 34 while( !que.empty() ) 35 { 36 int x = que.top(); 37 que.pop(); 38 ans[x] = id--; 39 set<int>::iterator it; 40 for(it = in[x].begin(); it != in[x].end(); it++) 41 { 42 out[*it].erase( x ); 43 if( ! out[*it].size() ) 44 { 45 que.push(*it); 46 } 47 } 48 } 49 for(int i = 1; i <= n; i++) 50 { 51 cout<<ans[i]<<' '; 52 } 53 }