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 }

 

posted @ 2016-05-22 19:42  fenicnn  阅读(130)  评论(0编辑  收藏  举报