• [HIHO1062] 最近公共祖先·一(lca, 并查集, 二分, 神trick)


    题目链接:http://hihocoder.com/problemset/problem/1062

    题意裸,有个trick,导致我当年做的时候一直在WA...

    那就是出现这种没有出现在关系中,但是依然可以知道他们关系的输入样例: LinDaiyu LinDaiyu

    应该输出自己。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 2021;
     5 int n, m, q;
     6 map<string, int> id;
     7 string di[maxn];
     8 vector<int> G[maxn];
     9 int depth[maxn], fa[maxn], in[maxn];
    10 char a[maxn], b[maxn];
    11 int pre[maxn];
    12 
    13 int find(int x) {
    14     return x == pre[x] ? x : pre[x] = find(pre[x]);
    15 }
    16 
    17 void unite(int x, int y) {
    18     x = find(x);
    19     y = find(y);
    20     if(x != y) pre[x] = y;
    21 }
    22 
    23 void dfs(int u, int p, int d) {
    24     depth[u] = d;
    25     fa[u] = p;
    26     for(int i = 0; i < G[u].size(); i++) {
    27         int &v = G[u][i];
    28         if(v == u || v == p) continue;
    29         dfs(v, u, d+1);
    30     }
    31 }
    32 
    33 int query(int u, int v) {
    34     if(find(u) != find(v)) return -1;
    35     if(depth[u] < depth[v]) swap(u, v);
    36     while(depth[u] > depth[v]) u = fa[u];
    37     while(u != v) {
    38         u = fa[u];
    39         v = fa[v];
    40     }
    41     return u;
    42 }
    43 
    44 int main() {
    45     // freopen("in", "r", stdin);
    46     while(~scanf("%d", &n)) {
    47         id.clear(); m = 0;
    48         memset(depth, 0, sizeof(depth));
    49         memset(in, 0, sizeof(in));
    50         for(int i = 0; i < maxn; i++) {
    51             pre[i] = i;
    52             G[i].clear();
    53         }
    54         for(int i = 0; i < n; i++) {
    55             scanf("%s %s", a, b);
    56             if(id.find(a) == id.end()) {
    57                 id[a] = ++m;
    58                 di[m] = a;
    59             }
    60             if(id.find(b) == id.end()) {
    61                 id[b] = ++m;
    62                 di[m] = b;
    63             }
    64             G[id[a]].push_back(id[b]);
    65             unite(id[a], id[b]);
    66             in[id[b]]++;
    67         }
    68         for(int i = 1; i <= m; i++) {
    69             if(!in[i]) {
    70                 dfs(i, -1, 1);
    71             }
    72         }
    73         scanf("%d", &q);
    74         while(q--) {
    75             scanf("%s %s", a, b);
    76             if(strcmp(a, b) == 0) {
    77                 puts(a);
    78                 continue;
    79             }
    80             if(id.find(a) == id.end() || id.find(b) == id.end()) {
    81                 puts("-1");
    82                 continue;
    83             }
    84             int ret = query(id[a], id[b]);
    85             if(ret == -1) puts("-1");
    86             else puts(di[ret].c_str());
    87         }
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    redis配置文件参数说明及命令操作
    在Window 下安装Redis数据库
    eclipse怎样在线安装hibernate tools插件并使用
    eclipse如何优化构建的速度(Building)
    java实现敏感词过滤(DFA算法)
    eclipse编码格式设置
    Jquery Ajax简单封装(集中错误、请求loading处理)
    Vue简单封装axios—解决post请求后端接收不到参数问题
    vue项目实现记住密码功能
    vue路由的两种模式配置以及history模式下面后端如何配置
  • 原文地址:https://www.cnblogs.com/kirai/p/6197145.html
Copyright © 2020-2023  润新知