zoukankan      html  css  js  c++  java
  • 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;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    根据基本表结构及其数据生成SQL语句
    (转)一个DbHelper数据操作类
    解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题 3法
    今天看到的一些软件工程管理的辅助软件
    编写维护状态的自定义WEB服务器控件
    webBrowser.execWB的完整说明
    [导入]在Web.Config中指定页面的基类
    [导入]一处 ADO.NET Entity Framework 的逻辑BUG
    [导入]在后台代码中引入XAML的方法
    选择排序(java版)
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9404495.html
Copyright © 2011-2022 走看看