hdu 2874 Connections between cities(lca->rmq)

來源:互聯網
上載者:User

標籤:des   style   blog   http   java   color   os   資料   

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 21 3 22 4 35 2 31 44 5

Sample Output

Not connected6

 

題意:給你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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.