• NBUT 2014 C Lord of Minecraft


    题目链接:http://acm.nbut.edu.cn/problem/view.xhtml?id=1554

    题意:给出一个n((nleq 10000))个节点的树,然后给出m((mleq100000))个询问,每个询问给出两个节点x和y,问从x到y的路径是否经过与x深度相同的节点?

    分析:

    用depth[k]表示标号为k的节点在树中的深度

    (1) 如果depth[x]>depth[y],显然不经过;如果depth[x]==depth[y],显然经过;如果depth[x]<depth[y],如果x是y的祖先节点,则不经过否则经过;

    (2) 根据(1),可以先计算出每个节点的深度,就能通过比较深度搞定询问中的前两种情况。对于depth[x]<depth[y],需要判断x是否为y的祖先

    (3) 这里不需要求出x,y的lca,只需要判断depth[x]<depth[y]时、x是否为y的祖先即可,显然dfs就可以做到,如果则x是y的祖先,那么dfs遍历到y时,x应该在栈中。

    (4) 可以离线操作:将询问中节点y对应的所有x放入y的队列中,当遍历到y时,直接判断x是否在栈中即可

    (5) 标程采用了另一中做法:按照dfs遍历的顺序维护一个标号flag,dfs时记录每个节点的标号范围,即进入一个节点x时l[x]=falg++,出x时r[x]=flag++,那么[ l[x], r[x] ]就是x的子孙的标号范围,这样通过比较范围可以确定x是否为y的祖先。

    题目给出的节点是字符串类型的,用map映射到int型

     1 # include <cstdio>
     2 # include <cstring>
     3 # include <map>
     4 # include <vector>
     5 # include <string>
     6 using namespace std;
     7 
     8 const int maxn = 10005;
     9 
    10 int n, m;
    11 map <string, int> mp;
    12 int root;
    13 vector <int> G[maxn];
    14 vector <int> Q[maxn];
    15 int d[maxn];
    16 
    17 char x[15], y[15];
    18 string sx, sy;
    19 
    20 int id;
    21 int ans;
    22 
    23 bool ins[maxn];
    24 void dfs_solve(int cur)
    25 {
    26     ins[cur] = true;
    27     for (int i = 0; i < Q[cur].size(); ++i) {
    28         if (ins[ Q[cur][i] ] == false) ++ans;
    29     }
    30     for (int i = 0; i < G[cur].size(); ++i) dfs_solve(G[cur][i]);
    31   ins[cur] = false;
    32 }
    33 void dfs_depth(int cur, int depth)
    34 {
    35     d[cur] = depth;
    36     for (int i = 0; i < G[cur].size(); ++i) dfs_depth(G[cur][i], depth+1);
    37 }
    38 int add(const string &s)
    39 {
    40     int ret = mp[s];
    41     if (ret < 1) ret = (mp[s] = ++id);
    42     return ret;
    43 }
    44 
    45 int main()
    46 {
    47     while (EOF != scanf("%d%d", &n, &m)) {
    48         mp.clear();
    49         for (int i = 1; i <= n+1; ++i) G[i].clear();
    50         id = 0;
    51         for (int i = 0; i < n; ++i) {
    52             scanf("%s%s", x, y);
    53             sx = x, sy = y;
    54             int ix = add(sx);
    55             int iy = add(sy);
    56             if (strcmp(y, "Hungar") == 0) root = iy;
    57             G[iy].push_back(ix);
    58         }
    59         for (int i = 1; i <= id; ++i) d[i] = 0;
    60         dfs_depth(root, 0);
    61         ans = 0;
    62         for (int i = 1; i <= id; ++i) Q[i].clear();
    63         for (int i = 0; i < m; ++i) {
    64             scanf("%s%s", x, y);
    65             sx = x, sy = y;
    66             int ix = mp[sx];
    67             int iy = mp[sy];
    68             if (d[ix] < d[iy]) Q[iy].push_back(ix);
    69             else if (d[ix] == d[iy]) ++ans;
    70         }
    71         for (int i = 1; i <= id; ++i) ins[i] = false;
    72         dfs_solve(root);
    73         printf("%d
    ", ans);
    74     }
    75 
    76     return 0;
    77 }
    1
     1 # include <cstdio>
     2 # include <cstring>
     3 # include <string>
     4 # include <map>
     5 # include <vector>
     6 using namespace std;
     7 
     8 const int maxn = 10005;
     9 
    10 int n, m;
    11 map <string, int> mp;
    12 vector <int> G[maxn];
    13 int d[maxn];
    14 int l[maxn], r[maxn];
    15 int id, root;
    16 char sx[15], sy[15];
    17 string stx, sty;
    18 int cnt;
    19 void dfs(int cur, int depth)
    20 {
    21     d[cur] = depth;
    22     l[cur] = cnt++;
    23     for (int i = 0; i < G[cur].size(); ++i) dfs(G[cur][i], depth+1);
    24     r[cur] = cnt++;
    25 }
    26 
    27 int add(const string &s)
    28 {
    29     return mp[s]>0 ? mp[s]:(mp[s]=++id);
    30 }
    31 
    32 void init(void)
    33 {
    34     id = 0;
    35     mp.clear();
    36     for (int i = 1; i <= n+1; ++i) G[i].clear();
    37     for (int i = 0; i < n; ++i) {
    38         scanf("%s%s", sx, sy); stx = sx, sty = sy;
    39         int x = add(stx), y = add(sty);
    40         if (strcmp(sy, "Hungar") == 0) root = y;
    41         G[y].push_back(x);
    42     }
    43     cnt = 0;
    44     dfs(root, 0);
    45 }
    46 
    47 void solve(void)
    48 {
    49     int ans = 0;
    50     for (int i = 0; i < m; ++i) {
    51         scanf("%s%s", sx, sy);
    52         stx = sx, sty = sy;
    53         int x = mp[stx];
    54         int y = mp[sty];
    55         if ((d[x]<d[y] && !(l[x]<l[y] && r[y]<r[x])) || (d[x]==d[y])) ++ans;
    56     }
    57     printf("%d
    ", ans);
    58 }
    59 
    60 int main()
    61 {
    62     while (EOF != scanf("%d%d", &n, &m)) {
    63         init();
    64         solve();
    65     }
    66     return 0;
    67 }
    2
  • 相关阅读:
    WinForm Settings.settings
    winform 按钮快捷键
    movie<人类消失后的世界>
    工作2周年
    vs 连接ms sql 2000失败解决方法
    编码速度
    javascript 类型速记
    C# winform CheckedListBox
    FrontEnd Develop Resource
    javascirpt Array
  • 原文地址:https://www.cnblogs.com/txd0u/p/3711387.html
Copyright © 2020-2023  润新知