HDU 2874 —— Connections between cities(并查集+LCA)

来源:互联网 发布:c语言简单的图形编程 编辑:程序博客网 时间:2024/06/05 14:38

题目:Connections between cities

题意:N个点的无向图,由于不存在环,所以形成的是森林。给出边的权值信息,询问u, v两个点之间是否连通,以及最短路径。

对于连通的问题,用并查集搞定。

而路径,由于两个点在同一棵树,可以先dfs预处理每个节点i到根节点的距离dist[i],无根树就随便找个结点当根啦。然后对于查询的u, v,找到它们的最近公共祖先p,答案就是dist[u]+dist[v]-2*dist[p]。

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;#define pb push_backconst int N = 10010;const int LOG_SIZE = 16;inline void in(int &x){    x=0;    char c=getchar();    while(c<48 || c>57) c=getchar();    while(c>=48 && c<=57){        x = x*10+c-48;        c = getchar();    }}vector<int> V[N], G[N];int n, m, q, fa[N];int find(int x){    int y = x;    for(; x!=fa[x]; x=fa[x]);    return fa[y]=x;}vector<int> P;int parent[LOG_SIZE][N], dist[N];int depth[N];void dfs(int x, int par){    P.pb(x);    for(int i=0; i<V[x].size(); i++){        int j = V[x][i];        if(j==par)  continue;        int v = G[x][i];        depth[j] = depth[x]+1;        parent[0][j] = x;        dist[j] = dist[x]+v;        dfs(j, x);    }}void init_lca(int x){    P.clear();    depth[x]=0;    dist[x]=0;    dfs(x, -1);    for(int k=0; k+1<LOG_SIZE; k++){for(int i=0; i<P.size(); i++){int v = P[i];if(parent[k][v]<0)parent[k+1][v] = -1;else{                parent[k+1][v] = parent[k][parent[k][v]];}}}}int lca(int u, int v){    if(depth[u] > depth[v]) swap(u, v);for(int k=0; k<LOG_SIZE; k++){if((depth[v]-depth[u]) >> k&1){v = parent[k][v];}}if(u==v)return u;for(int k=LOG_SIZE-1; k>=0; k--){if(parent[k][u] != parent[k][v]){u = parent[k][u];v = parent[k][v];}}return parent[0][u];}int query(int u, int v){    int p = lca(u,v);    return dist[u]+dist[v]-2*dist[p];}int main(){    while(~scanf("%d %d %d", &n, &m, &q)){        for(int i=1; i<=n; i++){            V[i].clear();            G[i].clear();            fa[i] = i;        }        int a, b, c;        while(m--){            in(a); in(b); in(c);            V[a].pb(b); G[a].pb(c);            V[b].pb(a); G[b].pb(c);            a = find(a);            b = find(b);            if(a!=b)    fa[a]=b;        }        for(int i=1; i<=n; i++){            if(fa[i]==i){                init_lca(i);            }        }        while(q--){            in(a); in(b);            if(find(a) != find(b))  puts("Not connected");            else    printf("%d\n", query(a, b));        }    }    return 0;}


0 0
原创粉丝点击