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 }
  • 相关阅读:
    执行一个外部程序并等待他的结束
    打开WORD文档时提示“word无法启动转换器mswrd632 wpc”的解决方法
    WaitForSingleObject的用法
    Delphi CreateProcess WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件
    webservices传base64字串
    webservices传文件
    webservices 字节数组 Base64编码
    内存映射大文件
    文件分割合并
    move
  • 原文地址:https://www.cnblogs.com/moomcake/p/9417601.html
Copyright © 2011-2022 走看看