HDU 5695 Gym Class 拓扑排序
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5695
题解:
求出字典序最大的拓扑序。然后把求好的数列翻转过来就是满足条件的数列,然后模拟求一下value就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 1e5 + 10; 9 typedef long long LL; 10 11 struct Edge { 12 int v, ne; 13 Edge(int v, int ne) :v(v), ne(ne) {} 14 Edge() {} 15 }egs[maxn*2]; 16 17 int n, m; 18 int head[maxn], ind[maxn],tot; 19 20 void addEdge(int u, int v) { 21 egs[tot] = Edge(v, head[u]); 22 head[u] = tot++; 23 } 24 25 void init() { 26 tot = 0; 27 memset(ind, 0, sizeof(ind)); 28 memset(head, -1, sizeof(head)); 29 } 30 31 int main() { 32 int tc; 33 scanf("%d", &tc); 34 while (tc--) { 35 init(); 36 scanf("%d%d", &n, &m); 37 for (int i = 0; i < m; i++) { 38 int u, v; 39 scanf("%d%d", &u, &v); 40 addEdge(u, v); 41 ind[v]++; 42 } 43 priority_queue<int> pq; 44 for (int i = 1; i <= n; i++) { 45 if (ind[i] == 0) pq.push(i); 46 } 47 vector<int> ans; 48 while (!pq.empty()) { 49 int u = pq.top(); pq.pop(); 50 ans.push_back(u); 51 int p = head[u]; 52 while (p != -1) { 53 Edge& e = egs[p]; 54 ind[e.v]--; 55 if (ind[e.v] == 0) { 56 pq.push(e.v); 57 } 58 p = e.ne; 59 } 60 } 61 LL sum = ans[0]; int mi = ans[0]; 62 for (int i = 1; i < ans.size(); i++) { 63 mi = min(mi, ans[i]); 64 sum += mi; 65 } 66 printf("%lld\n", sum); 67 } 68 return 0; 69 }