zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    json不支持中文写入的问题解决
    include(thinkphp常用内置标签)
    php如何设置编码格式
    模板替换
    获取网页内容之后图片不显示
    远程调用数据文件内容
    文件上传
    getError自动验证
    php文档编码设置
    获取网页内容时的乱码问题
  • 原文地址:https://www.cnblogs.com/moomcake/p/9417601.html
Copyright © 2011-2022 走看看