• hihocoder1067 最近公共祖先·二


    思路:

    使用tarjan算法,这是一种离线算法。

    实现:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<int, int> pii;
     4 const int MAXN = 100005;
     5 vector<int> G[MAXN], qry[MAXN];
     6 int par[MAXN], vis[MAXN];
     7 void init(int n)
     8 {
     9     for (int i = 0; i <= n; i++) par[i] = i;
    10 }
    11 int find(int x)
    12 {
    13     if (par[x] == x) return par[x];
    14     return par[x] = find(par[x]);
    15 }
    16 int uni(int x, int y)
    17 {
    18     x = find(x); y = find(y);
    19     if (x == y) return x;
    20     par[x] = y; return y;
    21 }
    22 void dfs(int u, int f, map<pii, int> & ans)
    23 {
    24     vis[u] = 1;
    25     for (auto it: qry[u])
    26     {
    27         int tmp = vis[it];
    28         if (!tmp) continue;
    29         if (tmp == 1)
    30             ans[pii(u, it)] = it;
    31         else if (tmp == 2)
    32             ans[pii(u, it)] = find(it);
    33     }
    34     for (int i = 0; i < G[u].size(); i++)
    35         if (!vis[G[u][i]]) dfs(G[u][i], u, ans);
    36     vis[u] = 2;
    37     uni(u, f);
    38 }
    39 int main()
    40 {
    41     int n, q;
    42     cin >> n;
    43     string x, y;
    44     map<string, int> mp;
    45     map<int, string> mp2;
    46     int id = 1, root = -1;
    47     for (int i = 0; i < n; i++)
    48     {
    49         cin >> x >> y;
    50         int pid = -1, sid = -1;
    51         if (!mp.count(x)) { mp[x] = pid = id; mp2[id] = x; id++; }
    52         else pid = mp[x];
    53         if (!mp.count(y)) { mp[y] = sid = id; mp2[id] = y; id++; }
    54         else sid = mp[y];
    55         if (i == 0) root = pid;
    56         G[pid].push_back(sid);
    57     }
    58     cin >> q;
    59     vector<pii> v;
    60     for (int i = 0; i < q; i++)
    61     {
    62         cin >> x >> y;
    63         int xid = mp[x], yid = mp[y];
    64         qry[xid].push_back(yid);
    65         qry[yid].push_back(xid);
    66         v.push_back(pii(xid, yid));
    67     }
    68     init(n);
    69     map<pii, int> ans;
    70     dfs(root, 0, ans);
    71     for (auto it: v)
    72     {
    73         int xid = it.first, yid = it.second;
    74         pii a(xid, yid), b(yid, xid);
    75         if (ans.count(a)) cout << mp2[ans[a]] << endl;
    76         else cout << mp2[ans[b]] << endl;
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    Emulator PANIC: Could not open: AVD2.3.1
    VC++ 6.0 快捷键
    eclipse 中文版 变成 英文版 方法
    SharedPreferences 用法
    subString
    Android键盘属性
    【Android异常】The specified child already has a parent. You must call removeView() on the child's parent first.
    ListView的ScrollListener
    Android 自定义格式的对话框
    Android ListView 设置
  • 原文地址:https://www.cnblogs.com/wangyiming/p/9166644.html
Copyright © 2020-2023  润新知