3 5 10 5 4 10 8 1 10 1 3 1 4 1 5 1 3 2 1 2 5 4 3 4 3 4 5 5 1 1 4 4 6 1 9 4 7 2 9 5 10 5 2 8 8 10 10 2 1 2 3 3 2 3 4 3 1 3 2 3 4 4 1 5 4 5 1 1 4 2 3 4 7 3 10 1 5 5 10 5 9 9 8 2 1 1 5 1 5 2 1 2 4 2 4 2 4 3 2 3 1 4 3 4 3 5 9 3 9 2 7 5 1 5 4
40 60 90 70 90 8 30 70 100 10 9 81 63 1
4
这道题总体来说比较好做,开始考试十分钟后就想出了做法。但是,,,,,,写完后有一个变量(num)忘清空了,就此丢了30分。
做法————tarjan缩点+拓扑dp。
另外,神仙rqy用BFS把标程踩了。
上我的代码
额,忘了保存,它没了,只能贴一下老师的了
#include <cstdio> #include <cstring> template <class cls> inline cls min(const cls & a, const cls & b) { return a < b ? a : b; } template <class cls> inline cls max(const cls & a, const cls & b) { return a > b ? a : b; } const int mxn = 200005; const int mxm = 400005; int n, m, k, w[mxn]; struct edge { int u, v; } edges[mxm]; int tot; int hd[mxn]; int to[mxm << 1]; int nt[mxm << 1]; inline void add_edge(int u, int v) { nt[++tot] = hd[u]; to[tot] = v; hd[u] = tot; } int tim; int cnt; int top; int dfn[mxn]; int low[mxn]; int stk[mxn]; int scc[mxn]; void tarjan(int u) { dfn[u] = low[u] = ++tim; stk[++top] = u; for (int e = hd[u], v; e; e = nt[e]) if (v = to[e], scc[v] == 0) { if (dfn[v] == 0)tarjan(v), low[u] = min(low[u], low[v]); else low[u] = min(low[u], dfn[v]); } if (dfn[u] == low[u]) { cnt += 1; do { scc[stk[top]] = cnt; } while (stk[top--] != u); } } int oe[mxn]; int mx[mxn]; int que[mxn]; void bfs() { int l = 0, r = 0; for (int i = 1; i <= cnt; ++i) if (oe[i] == 0) que[r++] = i; while (l < r) { int u = que[l++]; for (int e = hd[u], v; e; e = nt[e]) if (v = to[e], mx[v] = max(mx[v], mx[u]), --oe[v] == 0) que[r++] = v; } } int main() { int cas; scanf("%d", &cas); for (int c = 0; c < cas; ++c) { scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= n; ++i) scanf("%d", w + i); memset(hd, 0, sizeof(int) * (n + 5)); tot = 0; for (int i = 0; i < m; ++i) { scanf("%d%d", &edges[i].u, &edges[i].v); add_edge(edges[i].u, edges[i].v); } tim = cnt = top = 0; memset(scc, 0, sizeof(int) * (n + 5)); memset(dfn, 0, sizeof(int) * (n + 5)); for (int i = 1; i <= n; ++i) if (scc[i] == 0) tarjan(i); memset(hd, 0, sizeof(int) * (cnt + 5)); tot = 0; memset(oe, 0, sizeof(int) * (cnt + 5)); memset(mx, 0, sizeof(int) * (cnt + 5)); for (int i = 0; i < m; ++i) { int u = scc[edges[i].u]; int v = scc[edges[i].v]; if (u != v) add_edge(v, u), oe[u] += 1; } for (int i = 1; i <= n; ++i) mx[scc[i]] = max(mx[scc[i]], w[i]); bfs(); for (int i = 0, u, x; i < k; ++i) { scanf("%d%d", &u, &x); printf("%lld ", 1LL * x * mx[scc[u]]); } } return 0; }