zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    request相关
    C#请求接口
    qml_base
    web
    entry
    listbox
    Canvas
    pickle
    c#枚举
    数据结构——树
  • 原文地址:https://www.cnblogs.com/lcezfzy/p/11344610.html
Copyright © 2011-2022 走看看