• [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;
    }
  • 相关阅读:
    linux常用脚本
    shell学习笔记
    Linux常用命令List
    Centos7部署Zabbix
    centos7安装nagios步骤
    nagios报错HTTP WARNING: HTTP/1.1 403 Forbidden解决方法
    U盘安装CentOS7
    Thread线程控制之sleep、join、setDaemon方法的用处
    EfficientDet框架详解 | 目前最高最快最小模型,可扩缩且高效的目标检测(附源码下载)
    ubuntu18.04 安装多版本cuda ,原来版本为9.0,在新增8.0
  • 原文地址:https://www.cnblogs.com/kirai/p/5256183.html
Copyright © 2020-2023  润新知