zoukankan      html  css  js  c++  java
  • [HDOJ2586]How far away?(最近公共祖先 瞎写)

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

    给一个图,找两个点最近公共祖先。

    这几天数据取证课上得蛋疼,根本没有时间看什么算法。今晚翘课做大物实验,回来虽然没下课但是也不想去了。于是窝在实验室做一两道题爽一下也是不错的。

    膜拜一下tarjan,据说以tarjan命名的算法有三个,好强啊,什么时候我也能像他一样呢(恐怕一辈子都不可能了吧(笑))

    插入边的时候统计出入度,以便后来选择谁来做根节点。同时为了查询方便,我用map来存边。这道题解决完输入问题后,开始标记每一个节点在我刚刚标记的图上的层次遍历的深度和它的相应父节点,之后就可以查询最近公共祖先了,注意查询的时候先加边权再更新点。

    代码:

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <iomanip>
      4 #include <cstring>
      5 #include <climits>
      6 #include <complex>
      7 #include <fstream>
      8 #include <cassert>
      9 #include <cstdio>
     10 #include <bitset>
     11 #include <vector>
     12 #include <deque>
     13 #include <queue>
     14 #include <stack>
     15 #include <ctime>
     16 #include <set>
     17 #include <map>
     18 #include <cmath>
     19 
     20 using namespace std;
     21 
     22 typedef struct Edge {
     23     int u, v;
     24     int next;
     25 }Edge;
     26 
     27 typedef pair<int, int> pii;
     28 const int maxn = 40010;
     29 int n, m;
     30 int ecnt;
     31 int head[maxn];
     32 int depth[maxn], parent[maxn];
     33 int in[maxn], out[maxn];
     34 int root;
     35 map<pii, int> el;
     36 Edge e[maxn];
     37 
     38 void init() {
     39     ecnt = 0;
     40     el.clear();
     41     memset(head, -1, sizeof(head));
     42     memset(e, 0, sizeof(e));
     43 }
     44 
     45 void adde(int u, int v, int w) {
     46     e[ecnt].u = u;
     47     e[ecnt].v = v;
     48     in[v]++;
     49     out[u]++;
     50     e[ecnt].next = head[u];
     51     head[u] = ecnt++;
     52     el[pii(u, v)] = w;
     53 }
     54 
     55 void dfs(int u, int p, int d) {
     56     parent[u] = p;
     57     depth[u] = d;
     58     for(int i = head[u]; ~i; i = e[i].next) {
     59         if(p != e[i].v) {
     60             dfs(e[i].v, u, d+1);
     61         }
     62     }
     63 }
     64 
     65 int lca(int u, int v) {
     66     int ans = 0;
     67     while(depth[u] > depth[v]) {
     68         ans += el[pii(parent[u], u)];
     69         u = parent[u];
     70     }
     71     while(depth[v] > depth[u]) {
     72         ans += el[pii(parent[v], v)];
     73         v = parent[v];
     74     }
     75     while(u != v) {
     76         ans += el[pii(parent[u], u)];
     77         ans += el[pii(parent[v], v)];
     78         u = parent[u];
     79         v = parent[v];
     80     }
     81     return ans;
     82 }
     83 
     84 int main() {
     85     // freopen("in", "r", stdin);
     86     int T;
     87     int u, v, w;
     88     scanf("%d", &T);
     89     while(T--) {
     90         init();
     91         scanf("%d %d", &n, &m);
     92         for(int i = 0; i < n-1; i++) {
     93             scanf("%d %d %d", &u, &v, &w);
     94             adde(u, v, w);
     95         }
     96         for(int i = 1; i <= n; i++) {
     97             if(in[i] == 0) {
     98                 root = i;
     99                 break;
    100             }
    101         }
    102         dfs(root, -1, 0);
    103         while(m--) {
    104             scanf("%d %d", &u, &v);
    105             printf("%d
    ", lca(u, v));
    106         }
    107     }
    108     return 0;
    109 }

    也可以把map换成一个hash,数据太水可以这么搞。

    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    #include <cstring>
    #include <climits>
    #include <complex>
    #include <fstream>
    #include <cassert>
    #include <cstdio>
    #include <bitset>
    #include <vector>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <ctime>
    #include <set>
    #include <map>
    #include <cmath>
    
    using namespace std;
    
    typedef struct Edge {
        int u, v;
        int next;
    }Edge;
    
    typedef pair<int, int> pii;
    const int maxn = 40010;
    const int mod = 1111111;
    int n, m;
    int ecnt;
    int head[maxn];
    int depth[maxn], parent[maxn];
    int in[maxn], out[maxn];
    int root;
    int has[mod];
    Edge e[maxn];
    
    #define con(u, v) ((parent[u]*1005)%mod+(u*217)%mod)%mod
    
    void init() {
        ecnt = 0;
        memset(has, 0, sizeof(has));
        memset(head, -1, sizeof(head));
        memset(e, 0, sizeof(e));
    }
    
    void adde(int u, int v, int w) {
        e[ecnt].u = u;
        e[ecnt].v = v;
        in[v]++;
        out[u]++;
        e[ecnt].next = head[u];
        head[u] = ecnt++;
        has[((u*1005)%mod+(v*217)%mod)%mod] = w;
    }
    
    void dfs(int u, int p, int d) {
        parent[u] = p;
        depth[u] = d;
        for(int i = head[u]; ~i; i = e[i].next) {
            if(p != e[i].v) {
                dfs(e[i].v, u, d+1);
            }
        }
    }
    
    int lca(int u, int v) {
        int ans = 0;
        while(depth[u] > depth[v]) {
            ans += has[con(u, u)];
            u = parent[u];
        }
        while(depth[v] > depth[u]) {
            ans += has[con(v, v)];
            v = parent[v];
        }
        while(u != v) {
            ans += has[con(u, u)];
            ans += has[con(v, v)];
            u = parent[u];
            v = parent[v];
        }
        return ans;
    }
    
    int main() {
        // freopen("in", "r", stdin);
        int T;
        int u, v, w;
        scanf("%d", &T);
        while(T--) {
            init();
            scanf("%d %d", &n, &m);
            for(int i = 0; i < n-1; i++) {
                scanf("%d %d %d", &u, &v, &w);
                adde(u, v, w);
            }
            for(int i = 1; i <= n; i++) {
                if(in[i] == 0) {
                    root = i;
                    break;
                }
            }
            dfs(root, -1, 0);
            while(m--) {
                scanf("%d %d", &u, &v);
                printf("%d
    ", lca(u, v));
            }
        }
        return 0;
    }
  • 相关阅读:
    布局重用 include merge ViewStub
    AS 常用插件 MD
    AS 2.0新功能 Instant Run
    AS .ignore插件 忽略文件
    AS Gradle构建工具与Android plugin插件【大全】
    如何开通www国际域名个人网站
    倒计时实现方案总结 Timer Handler
    AS 进行单元测试
    RxJava 设计理念 观察者模式 Observable lambdas MD
    retrofit okhttp RxJava bk Gson Lambda 综合示例【配置】
  • 原文地址:https://www.cnblogs.com/kirai/p/5256183.html
Copyright © 2011-2022 走看看