• *51nod 1815


    从若干个数中选出最大的任意两数取模之后的结果

    严格次大值

    对于此题

    首先缩点

    然后拓扑排序

    维护到达每个点的最大值与严格次大值

    感觉思路与代码都OK啊

    then....

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <ctime>
    
    using namespace std;
    
    #define LL long long
    
    #define gc getchar()
    inline int read() {int x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
    inline LL read_LL() {LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
    #undef gc
    
    const int N = 4e5 + 10, M = 2e6 + 10;
    int n, m, S, Q;
    int A[N];
    
    int Dfn[N], Low[N], Belong[N], Beljs, Tim;
    bool vis[N];
    int Stack[N], topp;
    
    pair <int, int> Pair[N];
    struct Node {int u, v, nxt;} G[M];
    int head1[N], cnt;
    
    inline void Link(int u, int v) {G[++ cnt].v = v; G[cnt].nxt = head1[u]; head1[u] = cnt;}
    
    void Tarjan(int u) {
        Dfn[u] = Low[u] = ++ Tim;
        vis[u] = 1;
        Stack[++ topp] = u;
        for(int i = head1[u]; ~ i; i = G[i].nxt) {
            int v = G[i].v;
            if(!Dfn[v]) {
                Tarjan(v);
                Low[u] = min(Low[u], Low[v]);
            } else if(vis[v]) Low[u] = min(Low[u], Low[v]);
        }
        if(Low[u] == Dfn[u]) {
            int Max = 0, CMax = 0;
            Max = A[u];
            vis[u] = 0; Belong[u] = ++ Beljs;
            Pair[Beljs].first = A[u]; Pair[Beljs].second = -1;
            while(Stack[topp] != u) {
                int a  = Stack[topp];
                vis[a] = 0;
                Belong[a] = Beljs;
                topp --;
                if(A[a] > Max) {CMax = Max, Max = A[a];}
                else if(A[a] != Max) CMax = max(CMax, A[a]);
                Pair[Beljs] = make_pair(Max, CMax);
            } topp --;
        }
    }
    
    Node E[M];
    int head2[N], Du[N];
    
    inline void ReLink(int u, int v) {Du[v] ++; E[++ cnt].v = v; E[cnt].nxt = head2[u]; head2[u] = cnt;}
    
    int use[N];
    
    void Rebuild() {
        for(int i = 1; i <= Beljs; i ++) head2[i] = -1;
        cnt = 0;
        for(int u = 1; u <= n; u ++)
            for(int i = head1[u]; ~ i; i = G[i].nxt) {
                int v = G[i].v;
                if(Belong[u] != Belong[v] && use[Belong[v]] != u) {
                    use[Belong[v]] = u;
    //                cout << Belong[u] << " " << Belong[v] << "
    ";
                    ReLink(Belong[u], Belong[v]);    
                }
            }
    }
    
    int Que[N];
    
    bool beuse[N];
    
    void Topsort() {
        int h = 1, t = 0;
    //    for(int i = 1; i <= Beljs; i ++) if(Du[i] == 0) Que[++ t] = i;
        Que[++ t] = Belong[S];
        while(h <= t) {
            int topu = Que[h ++];
            beuse[topu] = 1;
            for(int i = head2[topu]; ~ i; i = E[i].nxt) {
                int v = E[i].v;
                Du[v] --;
                if(Du[v] == 0) Que[++ t] = v;
                int B[5];
    //            cout << Pair[topu].first << " " << Pair[topu].second << " " << Pair[v].first << " " << Pair[v].second << "
    ";
                B[1] = Pair[topu].first, B[2] = Pair[topu].second, B[3] = Pair[v].first, B[4] = Pair[v].second;
                sort(B + 1, B + 5);
                Pair[v].first = B[4];
                int j = 3;
                while(B[j] == B[4]) j --;
                Pair[v].second = B[j];
            }
        }
    }
    
    int main() {
    //    srand(time(0) - 99999);
    //    freopen("gg.in", "r", stdin);
    //    freopen("gg.out", "w", stdout);
        n = read(), m = read(), Q = read(), S = read();
        for(int i = 1; i <= n; i ++) A[i] = read();
        for(int i = 1; i <= n; i ++) head1[i] = -1;
        for(int i = 1; i <= m; i ++) {
            int u = read(), v = read();
            Link(u, v);
        }
        for(int i = 1; i <= n; i ++) 
            if(!Dfn[i])
                Tarjan(i);
    //    for(int i = 1; i <= Beljs; i ++) {
    //        cout << Pair[i].first << " " << Pair[i].second << "
    ";
    //    }
    //    return 0;
        Rebuild();
    //    for(int i = 1; i <= Beljs; i ++) {
    //        for(int j = head2[i]; ~ j; j = E[j].nxt) {
    //            int v = E[j].v;
    //            cout << i << " " << v << "
    ";
    //        }
    //    }
        Topsort();
        for(int i = 1; i <= Q; i ++) {
            int a = read();
            if(beuse[Belong[a]] == 0) cout << -1 << " ";
            else cout << Pair[Belong[a]].second << " ";
        //    if(ans == 0) cout << -1 << " ";
    //        cout << ans << " ";
        }
        return 0;
    }
    /*
    8 10 5 1
    5 5 5 7 5 5 5 5
    1 2
    2 3
    3 1
    3 4
    5 1
    6 5
    1 6
    6 8
    8 7
    7 6
    1 2 3 4 5
    */ 
  • 相关阅读:
    C++指针和引用及区别
    C/C++中extern关键字总结
    php进阶面试题总结
    算法疑难(js实现)---11、字典树
    Trie|如何用字典树实现搜索引擎的关键词提示功能
    ExtJS表格——行号、复选框、选择模型
    Ext.js 中 25种类型的Ext.panel.Tool
    Ext NumberField使用
    [ext]form.submit()相关说明
    ExtJS 表单 submit时错误处理
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9594371.html
Copyright © 2020-2023  润新知