hdu-2874 Connections between cities(lca+tarjan+并查集)

题目链接:

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 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

题意:

给了一些边,可能是一棵树,可能是森林,c个询问,问i和j之间的距离;

思路:

由于是森林,所以采用lca的离线算法Tarjan;开两个并查集,一个可以先预处理是否在一棵树上,另一个用在Tarjan上;

Tarjan算法的思想是一边处理,一边回答询问,把一个节点的所有子树处理完后就可以回答完关于这个节点的和所有已经处理完点的询问了;

AC代码:

/*
    2874    1731MS    29448K    2286 B    G++     2014300227
*/
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+4;
typedef long long ll;
const double PI=acos(-1.0);
int n,m,c,cnt,head[N],a,b,num,pre[N],p[N],l,r,v,dis[N],ans[1000005],vis[N],fa[N];
struct Edge
{
    int to,va,next;
};
Edge edge[2*N];
struct ques
{
    int to,next,id;
};
ques que[2000000+20];
void add(int s,int e,int v)
{
    //edge[cnt].fr = s;
    edge[cnt].to = e;
    edge[cnt].va=v;
    edge[cnt].next = head[s];
    head[s] = cnt++;//学会了这种存边的方法;
}
void q_add(int s,int e,int order)
{
    //que[num].fr = s;
    que[num].to = e;
    que[num].next = pre[s];
    que[num].id=order;
    pre[s] = num++;
}
int findset(int x)
{
    if(x == p[x])return x;
    return p[x] = findset(p[x]);
}
int fun(int x)
{
    if(x==fa[x])return x;
    return fa[x]=fun(fa[x]);
}
void Tarjan(int x,int dist)
{
    vis[x] = 1;
    dis[x]=dist;
    for(int i = head[x];i!=-1;i = edge[i].next)//head[x]指向以x为端点的一条边;下面的pre[x]也是相同的道理;
    {
        int y = edge[i].to;
        if(!vis[y])
        {
            Tarjan(y,dist+edge[i].va);
            fa[y] = x;
        }
    }//前边表示这个节点的所有子树已经处理完毕,下面可以回答相关的询问了;
    for(int i = pre[x];i!=-1;i = que[i].next)
    {
        int y = que[i].to;
        if(findset(x) == findset(y))
        {
            if(vis[y])
            ans[que[i].id] = dis[y]+dis[x]-2*dis[fun(y)];
        }
        else ans[que[i].id] = -1;
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&c)!=EOF)
    {
        for(int i = 0;i <= n;i++)
        {
            p[i] = i;
            fa[i] = i;
            head[i]=pre[i]=-1;
            vis[i]=0;
        }
        cnt = 0;
        num = 0;
        for(int i = 0;i < m;i++)
        {
            scanf("%d%d%d",&l,&r,&v);
            int fx=findset(l),fy=findset(r);
            if(fx!=fy)p[fx]=fy;//看是否在一个树上的并查集
            add(l,r,v);
            add(r,l,v);
        }
        for(int i = 0;i < c;i++)
        {
            scanf("%d%d",&a,&b);
            q_add(a,b,i);
            q_add(b,a,i);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                Tarjan(i,0);
            }
        }
        for(int i = 0;i < c;i++)
        {
            if(ans[i]>-1)printf("%d\n",ans[i]);
            else printf("Not connected\n");
        }
    }
    return 0;
}
时间: 2024-10-13 00:17:59

hdu-2874 Connections between cities(lca+tarjan+并查集)的相关文章

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-&gt;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 damag

hdoj 2874 Connections between cities 【Tarjan离线LCA】

题目:hdoj 2874 Connections between cities 题意:战争过后,一些城市毁坏了.意思图不连通,让你求任意两点的距离. 分析:很明显求LCA 但是图不连通,所以我们Tarjan的时候要对每个点进行.然后标记即可. 另外,这个题目卡vector,看来以后要学着用数组模拟邻接表了. AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector

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