• HDU


    题目大意:给出N个点。M条线,Q个询问,询问的是两点之间的最短距离

    解题思路:恶心的数据量,一不小心就超空间了
    这题给图不是张连通图,是森林,所以计算两点之间的最短距离时还要考虑一下是否在同一棵树中

    剩下的就是裸LCA了

    #include <cstdio>
    #include <cstring>
    
    #define N 10010
    #define M 20010
    #define C 2000010
    
    struct Edge{
        int to, next, dis;
    }E[M];
    
    struct Edge2{
        int to, next, w;
    }E2[C];
    
    int n, m, c, tot, tot2;
    int head[N], head2[N], dist[N], f[N], vis[N];
    
    void AddEdge(int u, int v, int dis) {
        E[tot].to = v; E[tot].next = head[u]; E[tot].dis = dis; head[u] = tot++;
        u = u ^ v; v = u ^ v; u = u ^ v;
        E[tot].to = v; E[tot].next = head[u]; E[tot].dis = dis; head[u] = tot++;
    }
    
    void AddEdge2(int u, int v) {
        E2[tot2].to = v; E2[tot2].next = head2[u]; E2[tot2].w = -1; head2[u] = tot2++;
        u = u ^ v; v = u ^ v; u = u ^ v;
        E2[tot2].to = v; E2[tot2].next = head2[u]; E2[tot2].w = -1; head2[u] = tot2++;
    }
    
    void init() {
        memset(head, -1, sizeof(head));
        memset(head2, -1, sizeof(head2));
        tot = tot2 = 0;
    
        int u, v, d;
        for (int i = 0; i < m; i++) {
            scanf("%d%d%d", &u, &v, &d);
            AddEdge(u, v, d);
        }
    
        for (int i = 0; i < c; i++) {
            scanf("%d%d", &u, &v);
            AddEdge2(u, v);
        }
    
        memset(vis, 0, sizeof(vis));
    }
    
    int find(int x) {
        return x == f[x] ? x : f[x] = find(f[x]);
    }
    
    void tarjan(int u, int time) {
        vis[u] = time;
        f[u] = u;
    
        int v;
        for (int i = head[u]; i != -1; i = E[i].next) {
            v = E[i].to;
            if (vis[v])
                continue;
            dist[v] = dist[u] + E[i].dis;
            tarjan(v, time);
            f[v] = u;
        }
    
        for (int i = head2[u]; i != -1; i = E2[i].next) {
            v = E2[i].to;
            if (vis[v] == time) 
                E2[i].w = E2[i^1].w = dist[u] + dist[v] - 2 * dist[find(v)];
        }
    
    }
    
    void solve() {
    
        int cnt = 1;
        for (int i = 1; i <= n; i++) {
            if (!vis[i]) {
                dist[i] = 0;
                tarjan(i, cnt);
            }
            cnt++;
        }
        for (int i = 0; i < tot2; i += 2) {
            if (E2[i].w == -1)
                printf("Not connected
    ");
            else  
                printf("%d
    ", E2[i].w);
        }
    }
    
    int main() {
        while (scanf("%d%d%d", &n, &m, &c) != EOF) {
            init();
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    CCS的一些问题
    SignalTapII新特性Storage Qualification
    信号发生器输出幅值与输出阻抗的关系
    关于print函数的一些细节问题探讨
    hp3020 打印机驱动完全卸载方法
    【转】Ruby Selenium 测试
    [nodejs]CoffeeScript里实现Mixin
    [Ruby]ARGF的使用
    【Groovy】使用Maven集成Groovy代码
    [nodejs]optimist库
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7374284.html
Copyright © 2020-2023  润新知