• L. Right Build bfs


    http://codeforces.com/gym/101149/problem/L

    给出一个有向图,从0开始,<u, v>表示要学会v,必须掌握u,现在要学会a和b,最小需要经过多少个点。

    做这题的时候,一看就觉得是先找出a和b点的lca,但是以前学的LCA是树的,现在这个是图。

    一定要知道LCA是树的,图的不行。

    然后下午去上课了,图中找了一个博客里说,求有向图得lca可以反向建图  + bfs来搞,(当时还不清楚LCA是用在树上的,一直以为可以。)具体思路是对两个起点进行了bfs,然后拿她们的bfs序来判断相交在哪里。然后就搞了一个晚上了,最后发现是不行的,有数据保证不行,因为bfs的时候也有先后之分,这个先后和你的边顺序有关,就不能确定了

    然后就想暴力吧,没一个a和b在反图上路径相同的点,都暴力去和答案更新最小值。

    TLE几次后就能过了,预处理出数组就可以过。

    给一些数据你们吧,找了一天的数据~~

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    
    const int maxn = 5e5 + 20;
    struct node {
        int u, v, tonext;
    } e[maxn];
    int num;
    int first[maxn];
    int used;
    void add(int u, int v) {
        ++num;
        e[num].u = u;
        e[num].v = v;
        e[num].tonext = first[u];
        first[u] = num;
    }
    int n, m, a, b;
    int ans;
    int book[maxn];
    int zero[maxn];
    struct bfsnode {
        int cur;
        int cnt;
        bfsnode(int a, int b) : cur(a), cnt(b) {}
    };
    queue<struct bfsnode>que, quese;
    int bfs(int begin, int end, int DFN) {
        if (begin == end) return 0;
        book[begin] = DFN;
        while (!quese.empty())  quese.pop();
        quese.push(bfsnode(begin, 0));
        while (!quese.empty()) {
            struct bfsnode t = quese.front();
            quese.pop();
            for (int i = first[t.cur]; i; i = e[i].tonext) {
                int v = e[i].v;
                if (book[v] == DFN) continue;
                if (v == end) return t.cnt + 1;
                zero[v] = t.cnt + 1;
                book[v] = DFN;
                quese.push(bfsnode(v, t.cnt + 1));
            }
        }
        return inf;
    }
    int first_two[maxn];
    struct Edge {
        int u, v, tonext;
    } e_two[maxn];
    int num_two;
    void add_two(int u, int v) {
        ++num_two;
        e_two[num_two].u = u;
        e_two[num_two].v = v;
        e_two[num_two].tonext = first_two[u];
        first_two[u] = num_two;
    }
    int bookA[2][maxn];
    int book_two[maxn];
    void BFS(int begin, int DFN, int now) {
        while (!que.empty()) que.pop();
        book_two[begin] = DFN;
        bookA[now][begin] = 0;
        if (bookA[!now][begin] != inf && zero[begin] != inf) {
            ans = min(bookA[now][begin] + bookA[!now][begin] + zero[begin], ans);
        }
        que.push(bfsnode(begin, 0));
        while (!que.empty()) {
            struct bfsnode t = que.front();
            que.pop();
            for (int i = first_two[t.cur]; i; i = e_two[i].tonext) {
                int v = e_two[i].v;
                if (book_two[v] == DFN) continue;
                book_two[v] = DFN;
                bookA[now][v] = t.cnt + 1;
                if (bookA[!now][v] != inf && zero[v] != inf) {
                    ++used;
                    int tans = zero[v] + bookA[now][v] + bookA[!now][v];
                    ans = min(ans, tans);
                }
                que.push(bfsnode(v, t.cnt + 1));
            }
        }
        return;
    }
    void find() {
        memset(bookA, 0x3f, sizeof bookA);
        ans = inf;
        used = 1;
        BFS(a, used, 0);
        ++used;
        BFS(b, used, 1);
        return;
    }
    
    int in[maxn];
    void work() {
        IOS;
        cin >> n >> m >> a >> b;
        if (a == b) while(1);
        for (int i = 1; i <= m; ++i) {
            int u, v;
            cin >> u >> v;
            add(u, v);
            add_two(v, u);
        }
        memset(zero, 0x3f, sizeof zero);
        zero[0] = 0;
        bfs(0, inf, 8);
        find();
        cout << ans << endl;
    }
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        work();
        return 0;
    }
    View Code

    11 12 1 6
    0 1
    1 2
    2 3
    3 4
    4 5
    4 8
    8 9
    9 10
    10 11
    6 4
    0 6
    5 6

    证明bfs找lca不行

    7 14 10 7
    0 1
    1 2
    2 3
    3 4
    3 5
    5 6
    9 10
    4 5
    5 7
    1 8
    8 7
    4 5
    6 9
    8 6

    证明普通LCA不行,因为lca用在树上

  • 相关阅读:
    第一周C语言作业
    C语言I博客园作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言II博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6049126.html
Copyright © 2020-2023  润新知