zoukankan      html  css  js  c++  java
  • Day10

    Country A and B are at war. Country A needs to organize transport teams to deliver supplies toward some command center cities.

    In order to ensure the delivery works efficiently, all the roads in country A work only one direction. Therefore, map of country A can be regarded as DAG( Directed Acyclic Graph ). Command center cities only received supplies and not send out supplies.

    Intelligence agency of country B is credibly informed that there will be two cities carrying out a critical transporting task in country A.

    As long as **any** one of the two cities can not reach a command center city, the mission fails and country B will hold an enormous advantage. Therefore, country B plans to destroy one of the nn cities in country A and all the roads directly connected. (If a city carrying out the task is also a command center city, it is possible to destroy the city to make the mission fail)

    Now country B has made qq hypotheses about the two cities carrying out the critical task.
    Calculate the number of plan that makes the mission of country A fail.

    InputThe first line contains a integer T(1T10)(1≤T≤10), denoting the number of test cases.

    In each test case, the first line are two integers n,mn,m, denoting the number of cities and roads(1n100,000,1m200,000)(1≤n≤100,000,1≤m≤200,000).
    Then mm lines follow, each with two integers uu and vv, which means there is a directed road from city uu to v(1u,vn,uv)(1≤u,v≤n,u≠v).

    The next line is a integer q, denoting the number of queries (1q100,000)(1≤q≤100,000)
    And then qq lines follow, each with two integers aa and bb, which means the two cities carrying out the critical task are aa and b(1a,bn,ab)(1≤a,b≤n,a≠b).

    A city is a command center if and only if there is no road from it (its out degree is zero).
    OutputFor each query output a line with one integer, means the number of plan that makes the mission of country A fail.Sample Input

    2
    8 8
    1 2
    3 4
    3 5
    4 6
    4 7
    5 7
    6 8
    7 8
    2
    1 3
    6 7
    3 2
    3 1
    3 2
    2
    1 2
    3 1

    Sample Output

    4
    3
    2
    2

    国家A和B处于战争状态。A国需要组织运输队向一些指挥中心城市提供物资。为了确保交付有效,A国的所有道路只能向一个方向发展。因此,国家A的地图可以被视为DAG。指挥中心城市只收到物资而不发送物资。B国的情报机构可靠地获悉,将有两个城市在A国执行关键的运输任务。只要两个城市中的任何一个都无法到达指挥中心城市,任务就会失败,B国将拥有巨大的优势。因此,B国计划摧毁A国的n个城市之一和所有直接连接的道路。(如果执行任务的城市也是指挥中心城市,则可以摧毁城市以使任务失败)现在,B国对这两个执行关键任务的城市提出了q假设。计算使国家A的任务失败的计划数量。

    思路:支配树,相当于求2点的lca到出度为0的点的数量,拓扑反向建树,DAG->拓扑排序->从出度为0的点开始反向建树->通过lca,因为该题可能有多个连通块,就把每个出度为0的点连接到一个多源上,方便统计

    const int maxm = 1e5+5;
    
    int head[maxm<<1], edgecnt, depth[maxm], grand[maxm][25], n, limit, in[maxm], que[maxm];
    
    struct edge{
        int u, v, nex;
    } edges[maxm<<1];
    
    void addedge(int u, int v) {
        edges[++edgecnt].u = u;
        edges[edgecnt].v = v;
        edges[edgecnt].nex = head[u];
        head[u] = edgecnt;
    }
    
    void init() {
        edgecnt = 0;
        memset(head, 0, sizeof(head));
        memset(in, 0, sizeof(in));
        memset(grand, 0, sizeof(grand));
        memset(depth, 0, sizeof(depth));
    }
    
    void toposort() {
        int l = 1, r = 1;
        for(int i = 1; i <= n; ++i)
            if(!in[i]) que[r++] = i;
        while(l < r) {
            int u = que[l++];
            for(int i = head[u]; i; i = edges[i].nex) {
                if(!--in[edges[i].v])
                    que[r++] = edges[i].v;
            }
        }
    }
    
    int lca(int a, int b) {
        if(a == b) return a;
        if(depth[a] > depth[b]) swap(a, b);
        for(int i = limit; i >= 0; --i) 
            if(depth[a] <= depth[b] - (1<<i)) b = grand[b][i];
        if(a == b) return a;
        for(int i = limit; i >= 0; --i)
            if(grand[a][i] == grand[b][i]) continue;
            else {
                a = grand[a][i], b = grand[b][i];
            }
        return grand[a][0];
    }
    
    void run_case() {
        init();
        int m, u, v, q;
        cin >> n >> m;
        for(int i = 0; i < m; ++i) {
            cin >> u >> v;
            addedge(u, v);
            in[v]++;
        }
        limit = floor(log(n+0.0)/log(2.0))+1;
        toposort();
        for(int i = n; i > 0; --i) {
            int u = que[i];
            if(!head[u]) {
                addedge(0, u);
                depth[u] = 1;
                continue;
            }
            int v = edges[head[u]].v;
            for(int j = edges[head[u]].nex; j; j = edges[j].nex) v = lca(v, edges[j].v);
            depth[u] = depth[v] + 1;
            grand[u][0] = v;
            for(int j = 1; j <= limit; ++j) grand[u][j] = grand[grand[u][j-1]][j-1];
        }
        cin >> q;
        while(q--) {
            cin >> u >> v;
            cout << depth[u] + depth[v] - depth[lca(u, v)] << "
    ";
        }
        
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        int t;
        cin >> t;
        while(t--)
            run_case();
        return 0;
    }
    View Code
  • 相关阅读:
    一往直前!贪心法
    Longest subarray of target sum
    动态规划-最长公共子序列/最长公共子串
    Short Encoding of Words
    Spiral Matrix
    Longest Repeating Character Replacement
    伤怀之美
    宁静是一种生产力
    POJ 2524 Ubiquitous Religions 【并查集】
    POJ 1611 The Suspects【并查集】
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12256572.html
Copyright © 2011-2022 走看看