zoukankan      html  css  js  c++  java
  • Hdu 4547 【最近公共祖先】.cpp

    题意:

      dos命令的cd操作有两个可执行方法

      cd ..    回到上一级目录

      cd 当前目录名/b/c/d     当前目录名到某一个子目录下

      

      给出你目录的关系,然后给出a b问最少经过几步可以从a走到b..

    思路:

      求出a和b的最近公共祖先,然后分4种情况讨论

      ①. a和b有一个公共祖先c,则用 c时间戳-a的时间戳+1(1步可以直接从c到b)

      ②. a是b的祖先,则只用1步就可以到达b点

      ③. b是a的祖先,则用a的时间戳-b的时间戳

      ④. a和b是同一个点,则答案是0

    Tips:

      求绝对值的函数还是得自己写..

      用algorithm的就wa了..

      因为algorithm里面的fabs参数和返回值都是double的..

    Code:

      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <string>
      4 #include <iostream>
      5 #include <cmath>
      6 #include <map>
      7 using namespace std;
      8 
      9 const int MAXM = 10000010;
     10 const int MAXN = 100010;
     11 
     12 int f[MAXN];
     13 int find(int x)
     14 {
     15     return f[x] == x?x:f[x] = find(f[x]);
     16 }
     17 
     18 struct Edge
     19 {
     20     int s;
     21     int to;
     22     int next;
     23     int lca;
     24 }edge[MAXM], qedge[MAXM];
     25 int head[MAXN], qhead[MAXN];
     26 int tot, qtot;
     27 
     28 void add(int s, int u)
     29 {
     30     edge[tot].to = u;
     31     edge[tot].next = head[s];
     32     head[s] = tot++;
     33 }
     34 
     35 void qadd(int s, int u)
     36 {
     37     qedge[qtot].s = s;
     38     qedge[qtot].to = u;
     39     qedge[qtot].next = qhead[s];
     40     qhead[s] = qtot++;
     41     qedge[qtot].s = u;
     42     qedge[qtot].to = s;
     43     qedge[qtot].next = qhead[u];
     44     qhead[u] = qtot++;
     45 }
     46 
     47 bool vis[MAXN];
     48 int dfn[MAXN];
     49 int ti;
     50 void LCA(int u)
     51 {
     52     f[u] = u;
     53     vis[u] = true;
     54     for (int i = head[u]; i != -1; i = edge[i].next)
     55         if (!vis[edge[i].to]) {
     56             dfn[edge[i].to] = dfn[u]+1;
     57             LCA(edge[i].to);
     58             f[edge[i].to] = u;
     59         }
     60     for (int i = qhead[u]; i != -1; i = qedge[i].next) {
     61         if (vis[qedge[i].to]) {
     62             qedge[i].lca = find(qedge[i].to);
     63             qedge[i^1].lca = qedge[i].lca;
     64         }
     65     }
     66 }
     67 
     68 int abs(int x) {
     69     return x>0?x:-x;
     70 }
     71 
     72 int main()
     73 {
     74     int in[MAXN];
     75     int T, n, q;
     76     int cnt, fa;
     77     char str1[45], str2[45];
     78     scanf("%d", &T);
     79     while (T--) {
     80         scanf("%d %d", &n, &q);
     81         map<string, int> M;
     82         cnt = 1;
     83         tot = qtot = 0;
     84         ti = 0;
     85 
     86         memset(head, 0xff, sizeof(head));
     87         memset(qhead, 0xff, sizeof(qhead));
     88         for (int i = 0; i <= n; ++i) {
     89             f[i] = i;
     90             vis[i] = false;
     91             dfn[i] = 0;
     92             in[i] = 0;
     93         }
     94         for (int i = 0; i < n-1; ++i) {
     95             scanf("%s %s", str1, str2);
     96             if (!M[str1]) M[str1] = cnt++;
     97             if (!M[str2]) M[str2] = cnt++;
     98             add(M[str2], M[str1]);
     99             in[M[str1]]++;
    100         }
    101         for (int i = 0; i < q; ++i) {
    102             scanf("%s %s", str1, str2);
    103             qadd(M[str1], M[str2]);
    104         }
    105         for (int i = 1; i <= n; ++i)
    106             if (in[i] == 0) {
    107                 fa = i;
    108                 break;
    109             }
    110         LCA(fa);
    111 
    112      //   for (int i = 1; i < cnt; ++i)
    113      //       printf("___%d %d\n", i, dfn[i]);
    114 
    115         for (int i = 0; i < qtot; ++i)
    116         if (i%2 == 0) {
    117           //  printf("%d %d___ %d\n", qedge[i].s, qedge[i].to, qedge[i].lca);
    118          //   printf("%d_____\n", qedge[i].lca);
    119        //  printf("___%d %d\n", dfn[qedge[i].s], dfn[qedge[i].lca]);
    120             if (qedge[i].to == qedge[i].s) puts("0");
    121             else if (qedge[i].lca == qedge[i].to) printf("%d\n", abs(dfn[qedge[i].s]-dfn[qedge[i].to]));
    122             else if (qedge[i].s == qedge[i].lca) puts("1");
    123             else printf("%d\n", abs(dfn[qedge[i].s]-dfn[qedge[i].lca])+1);
    124         }
    125     }
    126     return 0;
    127 }
    View Code

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547

  • 相关阅读:
    整理前端面试题1
    前端面试题2
    6.显示锁Lock 和 线程通信Condition
    5.创建执行线程的方式之三 :实现Callable 接口
    4.闭锁 CountDownLatch
    3.ConcurrentHashMap 锁分段机制 Copy-On-Write
    2.原子变量 CAS算法
    1.volatile关键字 内存可见性
    13.MyBatis注解式开发
    12.查询缓存
  • 原文地址:https://www.cnblogs.com/Griselda/p/3119265.html
Copyright © 2011-2022 走看看