• Connections between cities HDU


    题意:

        给出n个点m条边的图,c次询问 求询问中两个点间的最短距离。

    解析:

      Floyd会T,所以用到了最短路树。。具体思想为:

      设k为u和v的最近公共祖先 d[i] 为祖结点到i的最短距离  则dis[u][v] = d[u] + d[v] - 2*d[k]

      用tarjan的lca求即可

      把这题代码当作模板就好啦

      

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 10010, INF = 0x7fffffff;
    const int maxm = 1e6 + 10;
    int n, m, cnt1, cnt2, c;
    int head1[maxn], head2[maxn], f[maxn], d[maxn], vis[maxn];
    int res[maxm];
    
    
    struct node
    {
        int v, w, next;
    }Node[maxn*2];
    
    struct edge
    {
        int v, id, next;
    }Edge[maxm*2];
    
    void add1_(int u, int v, int w)
    {
        Node[cnt1].v = v;
        Node[cnt1].w = w;
        Node[cnt1].next = head1[u];
        head1[u] = cnt1++;
    }
    
    void add1(int u, int v, int w)
    {
        add1_(u, v, w);
        add1_(v, u, w);
    }
    
    void add2_(int u, int v, int id)
    {
        Edge[cnt2].v = v;
        Edge[cnt2].id = id;
        Edge[cnt2].next = head2[u];
        head2[u] = cnt2++;
    }
    
    void add2(int u, int v, int id)
    {
        add2_(u, v, id);
        add2_(v, u, id);
    }
    
    int find(int x)
    {
        return f[x]==x?x:(f[x] = find(f[x]));
    }
    
    int lca(int u, int deep, int root)
    {
        f[u] = u;
        d[u] = deep; 
        vis[u] = root;  // 标记属于的树
        for(int i=head1[u]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(vis[e.v] == -1)
            {
                lca(e.v, deep+e.w, root);
                f[e.v] = u;
            }
        }
        for(int i=head2[u]; i!=-1; i=Edge[i].next)
        {
            edge e = Edge[i];
            if(vis[e.v] == root)   //判断另一个结点是不是和u属于一个树
            {
                int k = find(e.v);  //寻找最近公共祖先
                res[e.id] = d[u] + d[e.v] - 2*d[k];
            }
        }
    }
    
    void init()
    {
        mem(head1, -1);
        mem(head2, -1);
        mem(res, -1);
        mem(vis, -1);
        cnt1 = cnt2 = 0;
    }
    
    
    int main()
    {
        while(scanf("%d%d%d", &n, &m, &c) != EOF)
        {
            init();
            rap(i, 1, m)
            {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                add1(u, v, w);
            }
            rap(i, 1, c)
            {
                int u, v;
                scanf("%d%d", &u, &v);
                add2(u, v, i);
            }
            rap(i, 1, n)
                if(vis[i] == -1)
                    lca(i, 0, i);
            rap(i, 1, c)
            {
                if(res[i] == -1) printf("Not connected
    ");
                else printf("%d
    ", res[i]);
            }
        }
    
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    小甲鱼Python第021讲函数:lambda表达式 | 课后测试题及参考答案
    小甲鱼Python第020讲函数:内嵌函数和闭包 | 课后测试题及参考答案
    How to reference two table when lack reference column.
    how find a record import other database.
    when create a table,then show error ora-00952 tablespace tsb_1 not exist
    TELNET_COMMAND
    ORACLE_SPOOL
    OFFICE_EXCEL_Combine text from two or more cells into one cell.
    ORACLE_LPAD_FUNCTION
    ORACLE_PROCEDURE_DROPTABLE
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9404495.html
Copyright © 2020-2023  润新知