zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    【C++程序员学 python】python 的文件类型
    Python如何下载文件
    【C++程序员学 python】python split and join 分割与合并
    知道创宇研发技能表v2.1
    Scapy:局域网MAC地址扫描脚本
    LeetCode: Linked List Cycle II 解题报告
    LeetCode: Insertion Sort List 解题报告
    Lintcode: Minimum Adjustment Cost 解题报告
    LeetCode: Merge Two Sorted Lists 解题报告
    LeetCode: Palindrome Partitioning II 解题报告
  • 原文地址:https://www.cnblogs.com/kirai/p/6197145.html
Copyright © 2011-2022 走看看