8.11考试T2

 

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;
}

  

原文地址:https://www.cnblogs.com/lcezfzy/p/11344610.html