• Tarjan算法


      做了几道题之后才发现Tarjan写了这么多牛逼的算法。

      目前我所学的Tarjan经常用的算法主要就两个:

      1.Tarjan算法求连通量.

      2.Tarjan离线算法求CLA ( Cloest common ancestor)

      第一种比较好理解,第二种就不那么好理解了。

      推荐两个写的比较好的博客:

      1.http://alanyume.com/130.html

      2.http://www.cnblogs.com/jackge/archive/2013/05/10/3071437.html

      Tarjan离线算法的核心就是 DFS 和 并查集 。通过DFS不断将下面的点不断向上合并,在利用DFS的特性,find_set(u)的时候得到的结果就刚好是Cloest Common Ancestor了。

    例题:

    H - Closest Common Ancestors
    Time Limit:2000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u
    Appoint description:
     

    Description

    Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The closest common ancestor of two nodes u and v is the node w that is an ancestor of both u and v and has the greatest depth in the tree. A node can be its own ancestor (for example in Figure 1 the ancestors of node 2 are 2 and 5)

    Input

    The data set, which is read from a the std input, starts with the tree description, in the form:

    nr_of_vertices
    vertex:(nr_of_successors) successor1 successor2 ... successorn
    ...
    where vertices are represented as integers from 1 to n ( n <= 900 ). The tree description is followed by a list of pairs of vertices, in the form:
    nr_of_pairs
    (u v) (x y) ...

    The input file contents several data sets (at least one).
    Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.

    Output

    For each common ancestor the program prints the ancestor and the number of pair for which it is an ancestor. The results are printed on the standard output on separate lines, in to the ascending order of the vertices, in the format: ancestor:times
    For example, for the following tree:

    Sample Input

    5
    5:(3) 1 4 2
    1:(0)
    4:(0)
    2:(1) 3
    3:(0)
    6
    (1 5) (1 4) (4 2)
          (2 3)
    (1 3) (4 3)

    Sample Output

    2:1
    5:5

    Hint

    Huge input, scanf is recommended.
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<iomanip>
    #include<queue>
    #include<cstring>
    #include<vector>
    using namespace std;
    typedef long long LL;
    const int maxN = 1100;
    int n, m;
    int fa[maxN], head[maxN], vis[maxN], ans[maxN];
    vector<int> edge[maxN];
    int query[maxN][maxN];
    
    void init(){
        memset(fa, 0, sizeof(fa));
        memset(head, 0, sizeof(head));
        memset(vis, 0, sizeof(vis));
        memset(ans, 0, sizeof(ans));
        memset(query, 0, sizeof(query));
        for(int i=0 ; i<n; ++i) edge[i].clear();
    }
    
    int find_set(int u){
        if(u == fa[u])  return fa[u];
        return fa[u] = find_set(fa[u]);
    }
    
    void LCA(int u){
        fa[u] = u;
        for(int i=0 ; i<edge[u].size(); ++i){
            LCA(edge[u][i]);
            fa[edge[u][i]] = u;
        }
        vis[u] = 1;
        for(int i=1 ; i<=n;++i){
            if(query[u][i] && vis[i]){
                ans[find_set(i)] += query[u][i];
            }
        }
    }
    
    
    int main(){
        while(scanf("%d", &n)!=EOF){
            init();
            for(int i=1 ; i<=n; ++i){
                int a, b;
                scanf("%d:(%d)", &a, &b); //注意输入部分
                for(int j=0 ; j<b ; ++j){
                    int f;
                    scanf(" %d", &f);
                    head[f] = 1;
                    edge[a].push_back(f);
                }
            }
            scanf(" %d", &m);
            for(int i=0 ; i<m; ++i){
                int a, b;
                scanf(" (%d %d)", &a, &b);//注意输入部分
                query[a][b]++;
                query[b][a]++;
            }
            int start = 0;
            for(int i=1 ; i<=n; ++i){
                if(head[i]!= 1) start = i;
            }
            LCA(start);
            for(int i=1 ; i<=n; ++i){
                if(ans[i])  printf("%d:%d
    ", i, ans[i]);
            }
        }
        return 0;
    }

     

  • 相关阅读:
    【视频开发】【电子电路技术】监控球机PTZ的功能介绍
    【电子电路技术】PoE供电技术的优缺点
    【电子电路技术】PoE供电技术的优缺点
    【python开发】利用PIP3的时候出现的问题Fatal error in launcher: Unable to create process using '"'
    【python开发】利用PIP3的时候出现的问题Fatal error in launcher: Unable to create process using '"'
    【Python开发】C和Python之间的接口实现
    Nginx配置域名转发实例
    Nginx配置域名跳转实例
    MySQL查看数据库大小、表大小和最后修改时间
    iptables阻止服务器被攻击
  • 原文地址:https://www.cnblogs.com/topW2W/p/5240645.html
Copyright © 2020-2023  润新知