hdu 2874 Connections between cities(lca->rmq)

Connections between cities

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4425    Accepted Submission(s): 1263

Problem Description

After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads had been totally destroyed during the war, there might be no path between two cities, no circle exists as well.
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.

Input

Input consists of multiple problem instances.For each instance, first line contains three integers n, m and c, 2<=n<=10000, 0<=m<10000, 1<=c<=1000000. n represents the number of cities numbered from 1 to n. Following m lines, each line has three integers i, j and k, represent a road between city i and city j, with length k. Last c lines, two integers i, j each line, indicates a query of city i and city j.

Output

For each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them.

Sample Input


5 3 2
1 3 2
2 4 3
5 2 3
1 4
4 5

Sample Output


Not connected
6

 

题意:给你n给点,m条边,有c次询问,每次询问u,v两个点,你需要判断u,v是否连通,u,v的最短距离是多少。

 

::对于是否连通直接用并查集就可以了,对于连通的两个点最短距离怎么求呢。

数据很大,不允许每次询问都跑一次最短路的算法,那么就考虑一下一劳永逸的办法,有没有办法经过预处理,每次询问都能快速给出答案。

注意到这是无欢图,那没就转化成树的做法。

对于单个连通分量随意取一点,令其为根,进行dfs遍历,得到每个点到根结点的距离,保存起来(我这里用dp保存),并且得到一个dfs遍历的寻列,求出每两个点的lca。如何求lca具体看

lca –> rmq. 那么对于询问在同一个连通分量的两个的距离dis(u,v) = dp(u)+dp(v)-2*dp(lca(u,v));//u到根结点的距离+v到根结点的距离-(u,v)最早公共祖先到根结点的距离的2倍

 

view code#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int n, m, c, fa[N], pre[N], id[N], now, dp[N];
int E[N<<1], pos, R[N], d[N<<1][15];
bool vis[N];

struct edge
{
    int u, v, w, p;
    edge() {}
    edge(int u, int v,int w, int p):u(u), v(v), w(w), p(p) {}
}e[N<<1];
int ecnt;

int find(int x)
{
    return x==fa[x]?x:(fa[x]=find(fa[x]));
}

void init_RMQ()
{
    for(int i=0; i<pos; i++) d[i][0] = E[i];
    for(int j=1; (1<<j)<pos; j++)
        for(int i=0; i+(1<<j)-1<pos; i++)
            d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);
}

int RMQ(int L, int R)
{
    int k=0;
    while((1<<(k+1)) <= R-L+1) k++;
    return min(d[L][k], d[R-(1<<k)+1][k]);
}

void dfs(int u, int h)
{
    vis[u] = 1;
    id[u] = now++;//给每个结点一个新的id,为什么要给新的id,为什么不用原来的序号,弄懂求lca就懂了
    R[id[u]] = pos;
    E[pos++] = id[u];
    dp[id[u]] = h;//结点id[u]到根结点的距离为h
    for(int i=pre[u]; ~i; i=e[i].p)
    {
        int v = e[i].v;
        if(vis[v]) continue;
        dfs(v, h+e[i].w);
        E[pos++] = id[u];
    }
}

void init()
{
    memset(vis, 0, sizeof(vis));
    now = 1; pos = 0;
    for(int i=1; i<=n; i++) if(!vis[i]) dfs(i, 0);
//    for(int i=1; i<=n; i++) printf("is[%d] = %d,  R=%d\n", i, id[i], R[id[i]]);
//    for(int i=0; i<pos; i++) printf("pos[%d] = %d\n", i, E[i]);
    init_RMQ();
}

void solve()
{
    for(int i=1; i<=n; i++) fa[i] = i, pre[i] = -1;
    ecnt = 0;
    int u, v, w;
    for(int i=0; i<m; i++)
    {
        scanf("%d%d%d", &u, &v, &w);
        e[ecnt] = edge(u, v, w, pre[u]);
        pre[u] = ecnt++;
        e[ecnt] = edge(v, u, w, pre[v]);
        pre[v] = ecnt++;
        u =find(u), v =find(v);
        fa[u] = v;
    }
    init();
    while(c--)
    {
        scanf("%d%d", &u, &v);
        if(find(u)!=find(v)){
            puts("Not connected");
            continue;
        }
        u = id[u], v = id[v];
        int lca = RMQ(min(R[u], R[v]), max(R[u],R[v]));
        int ans = dp[u]+dp[v]-2*dp[lca];
        printf("%d\n", ans);
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d%d%d", &n, &m, &c)>0) solve();
    return 0;
}

hdu 2874 Connections between cities(lca->rmq)

时间: 2024-11-13 04:38:03

hdu 2874 Connections between cities(lca->rmq)的相关文章

HDU - 2874 Connections between cities(LCA)

题目大意:给出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

HDU 2874 Connections between cities(LCA离线)

 题意:一个森林,询问两个节点距离,若无法到达,输出Not connected. 思路:还是求LCA的思想,只需再对每个询问的两个节点判断是否在一棵树内即可. 有一个问题是这道题的query很大,达到了1000000,所以离线算法空间上比较虚, 然而只会离线的.....于是把int改成short int险过.... #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #

HDU 2874 Connections between cities (离线LCA)

题目地址:HDU 2874 好坑的一道题..MLE了好长时间....全用了前向星而且把G++改成了C++才过了.. LCA裸题,没什么好说的.. 代码如下; #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #in

hdu 2874 Connections between cities 带权lca判是否联通

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some mat

HDU——2874 Connections between cities

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11927    Accepted Submission(s): 2775 Problem Description After World War X, a lot of cities have been seriously dama

HDU 2874 Connections between cities(LCA离线算法实现)

http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意: 求两个城市之间的距离. 思路: LCA题,注意原图可能不连通. 如果不了解离线算法的话,可以看我之前博客写的解释http://www.cnblogs.com/zyb993963526/p/7295894.html 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cs

HDU - 2874 Connections between cities (LCA)

After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads h

hdu 2874 Connections between cities hdu 2586 How far away ? LCA

两道lca模板题,用的是倍增法,nlogn预处理,logn查询. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define maxn 10100 struct Edge { int u,v,w,next; }e[100100]; int n,m,c; int head[maxn],cnt; int fa[ma

Hdu 2874 Connections between cities

题意: 城市 道路  没有环 不一定连通的树 求两城市的最短距离 设想一下就是很多小树  那好办 思路: lca离线算法 然后有个技巧就是 每次我们tarjan一棵树不是最后树的节点都访问过并且孩子全能找到根嘛 那么我们只要做做做做 做到全部的城市都访问过了  就行了 反正你做这颗小树的时候又不会影响到其他树的 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; i