hdoj2874 -- Connections between cities(LCA--tarjan离线)

Connections between cities

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

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

Hint

Hint

Huge input, scanf recommended.

Source

2009 Multi-University Training Contest 8 - Host by BJNU

Recommend

gaojie   |   We have carefully selected several similar problems for you:  2873 2876 2872 2875 2877

最短路;

#include <cstdio>
#include <cstring>

#define N 10010
#define M 20010
#define C 2000010

struct Edge{
    int to, next, dis;
    Edge() {}
    Edge(int to, int dis, int next): to(to), dis(dis), next(next){};
}E[M];

struct Edge2{
    int to, next, w;
    Edge2() {}
    Edge2(int to, int w, int next): to(to), w(w), next(next) {};
}E2[C];

int n, m, c, tot, tot2;
int head[N], head2[N], dis[N], f[N], vis[N];

void addEdge(int u, int v, int dis){
    E[tot]= Edge(v, dis, head[u]);
    head[u]=tot++;
    E[tot]= Edge(u, dis, head[v]);
    head[v]=tot++;
}

void addEdge2(int u, int v){
    E2[tot2]= Edge2(v, -1, head2[u]);
    head2[u]=tot2++;
    E2[tot2]= Edge2(u, -1, head2[v]);
    head2[v]=tot2++;
}
/*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; i=E[i].next)
    {
        v=E[i].to;
        if(vis[v])
            continue;
        dis[v]= dis[u]+ E[i].dis;
        tarjan(v, time);
        f[v]= u;
    } 

    for(int i= head2[u]; ~i; i=E2[i].next)
    {
        v=E2[i].to;
        if(vis[v]== time)
            E2[i].w= E2[i^1].w = dis[u]+dis[v]- 2*dis[find(v)];
    }
}
void solve()
{
    int cnt=1;
    for(int i=1; i<=n; i++){
        if(!vis[i]){
            dis[i]= 0;
            tarjan(i, cnt);
        }
        cnt++;
    }

    for(int i=0; i< tot2; i +=2){
        if(E2[i].w == -1)
            printf("Not connected\n");
        else
            printf("%d\n", E2[i].w)  ;
    }
}
int main()
{
    while(scanf("%d%d%d", &n, &m, &c) != EOF)
    {
        init();
        solve();
    }
    return 0;
}
时间: 2024-10-11 15:16:08

hdoj2874 -- Connections between cities(LCA--tarjan离线)的相关文章

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+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, s

HDU 2874 Connections between cities(LCA离线)

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

hdu2874(lca / tarjan离线 + RMQ在线)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意: 给出 n 个顶点 m 条边的一个森林, 有 k 个形如 x y 的询问, 输出 x, y 之间的最短路径. 思路: 如果将森林换成一棵树的话就是一道 lca 模板题了, 不过本题需要稍作改动. 解法1: tarjan 只需要先判断一下 x, y 是否在一颗树里面就 ok 了, 不过这道题的询问有点多, 很容易 mle. 代码: 1 #include <iostream> 2 #in

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

poj3728(lca / tarjan离线)

题目链接: http://poj.org/problem?id=3728 题意: 给出一棵带点权值的树, 对于 q 组形如 x, y 的询问, 一个人要从 x 到 y(单向), 他可以在路上任意一点以此点的的权值买一件物品, 并在接下来的路程中任意一点将其以该点的权值卖出, 输出其最大收益, 若不能获益则输出 0 . 思路: 若不考虑时间复杂度的话对于询问 x, y. 可以先求出 lca(x, y), 然后再 x -> lca -> y 路径上求一下最大收益即可. 然而这样会 tle. 可以考

POJ 1330 最近公共祖先LCA(Tarjan离线做法)

题目链接:http://poj.org/problem?id=1330 题目大意十分明了简单,就是给定一棵树,求某两个子节点的最近公共祖先,如果尚不清楚LCA的同学,可以左转百度等进行学习. 稍微需要注意的是,建树顺序需要按照题目给定的顺序进行,也就是说根被设定成第一个给出的结点,如样例2. 此题网上题解颇多,但是多是使用的邻接表存图,于是我这里采用了边表,不过实质上Tarjan的部分思想都是一样的,均利用了并查集. AC代码: #include <cstdio> #include <c

Connections between cities LCA

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.

POJ 1330 Nearest Common ancesters(LCA,Tarjan离线算法)

Description: In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of node y if node x is in the path between the root and node y. For example, node 4 is an ancestor of node 16.