• [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;
    }
  • 相关阅读:
    mac安装protobuf2.4.1时报错./include/gtest/internal/gtest-port.h:428:10: fatal error: 'tr1/tuple' file not found和google/protobuf/message.cc:175:16: error: implicit instantiation of undefined template
    java基础六 [异常处理](阅读Head First Java记录)
    安装和使用iOS的包管理工具CocoaPods
    Node.js的知识点框架整理
    java基础五 [数字与静态](阅读Head First Java记录)
    java基础四 [构造器和垃圾回收](阅读Head First Java记录)
    Appium学习路-安装篇
    Dell笔记本Ubuntu无线网卡驱动安装
    Ubuntu系统使用命令禁用触摸板等输入设备
    linux(ubuntu) 查看系统设备信息
  • 原文地址:https://www.cnblogs.com/kirai/p/5256183.html
Copyright © 2020-2023  润新知