• Closest Common Ancestors


    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.
    题意:求最近公共祖先,模板题。
      1 #include <iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<queue>
      6 #include<map>
      7 #include<algorithm>
      8 typedef long long ll;
      9 using namespace std;
     10 const int MAXN=1e3+10;
     11 int m,n;
     12 int visit[MAXN];
     13 int is_root[MAXN];
     14 int str[MAXN];
     15 int head[MAXN];//以第i条边为起点的最后输入的那个编号
     16 int ans[MAXN];
     17 int mp[MAXN][MAXN];
     18 int cnt,root,x,y,cx,cy;
     19 struct node
     20 {
     21     int to;//边的终点
     22     int next;//与第i条边同起点的一条边的存储位置
     23     int vi;//权值
     24 }edge[MAXN];
     25 void add_edge(int x,int y)
     26 {
     27     edge[cnt].to=y;
     28     edge[cnt].next=head[x];
     29     head[x]=cnt++;
     30 }
     31 void init()
     32 {
     33     cnt=1;
     34     memset(visit,0,sizeof(visit));
     35     memset(mp,0,sizeof(mp));
     36     memset(ans,0,sizeof(ans));
     37     memset(is_root,true,sizeof(is_root));
     38     memset(head,-1,sizeof(head));
     39     for(int i=1;i<=m;i++)
     40     {
     41         str[i]=i;
     42     }
     43     int p,k;
     44     for(int i=1;i<=m;i++)
     45     {
     46         scanf("%d:(%d)",&p,&k);
     47         for(int j=1;j<=k;j++)
     48         {
     49          scanf("%d",&x);
     50          add_edge(p,x);
     51          is_root[x]=false;
     52         }
     53 
     54     }
     55     for(int i=1;i<=m;i++)//找根节点(入度为0的点)
     56     {
     57         if(is_root[i])
     58         {
     59             root=i;
     60             break;
     61         }
     62     }
     63 }
     64 int Find(int x)
     65 {
     66     int temp=x;
     67     while(temp!=str[temp])
     68     {
     69         temp=str[temp];
     70     }
     71     return temp;
     72 }
     73 void Unit(int x,int y)
     74 {
     75     int root1=Find(x);
     76     int root2=Find(y);
     77     if(root1!=root2)
     78     {
     79         str[y]=root1;
     80     }
     81 }
     82 void LCA(int u)
     83 {
     84     for(int i=head[u];i!=-1;i=edge[i].next)
     85     {
     86         int v=edge[i].to;
     87         LCA(v);
     88         Unit(u,v);
     89         visit[v]=true;
     90     }
     91     for(int i=1;i<=m;i++)//遍历图中所有点,找出与当前顶点u有关系的点,若该点i已访问,则找到v,i的lca;
     92     {
     93         if(visit[i]&&mp[u][i])
     94         {
     95             int k=Find(i);
     96             ans[k]+=mp[u][i];
     97         }
     98     }
     99 }
    100 void solve()
    101 {
    102     scanf("%d",&n);
    103     for(int i=1;i<=n;i++)
    104     {
    105         scanf(" (%d%d)",&cx,&cy);
    106         mp[cx][cy]++;
    107         mp[cy][cx]++;
    108     }
    109     LCA(root);
    110 }
    111 void output()
    112 {
    113     for(int i=1;i<=m;i++)
    114     {
    115         if(ans[i])
    116         {
    117             printf("%d:%d
    ",i,ans[i]);
    118         }
    119     }
    120 }
    121 int main()
    122 {
    123     while(scanf("%d",&m)!=-1)
    124     {
    125         init();
    126         solve();
    127         output();
    128     }
    129     return 0;
    130 }
  • 相关阅读:
    Session问题-一个部门A登录后未注销另一个部门B再登录,以B的身份操作A的成员
    Windows Server2008安装mysql5.6出现程序无法正常启动(0xc000007b)
    百度定位SDK
    Dubbo项目一段时间后提供者消失
    百度安卓SDK秘钥Key错误
    XGBoost类库使用小结
    支持向量机原理(五)线性支持回归
    主成分分析(PCA)原理总结
    scikit-learn 和pandas 基于windows单机机器学习环境的搭建
    梯度提升树(GBDT)原理小结
  • 原文地址:https://www.cnblogs.com/moomcake/p/9417601.html
Copyright © 2020-2023  润新知