zoukankan      html  css  js  c++  java
  • [hdu2874]Connections between cities(LCA+并查集)

    题意:n棵树,求任意两点的最短距离。

    解题关键:并查集判断两点是否位于一棵树上,然后求最短距离即可。此题可以直接对全部区间直接进行st表,因为first数组会将连接的两点的区间表示出来。

      1 //#pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<iostream>
      8 typedef long long ll;
      9 using namespace std;  
     10 const int maxn=11000; 
     11 const int maxm=25;  
     12 int _pow[maxm],m,n;  
     13 int head[maxn],tot;
     14 int ver[maxn*2],depth[maxn*2],first[maxn],rmq[maxn*2][25],id;//5个数组,注意哪个需要乘2 
     15 ll dis[maxn];
     16 int par[maxn];
     17 inline int read(){
     18     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
     19     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
     20     if(k=='-')x=0-x;return x;
     21 }
     22 
     23 struct edge{
     24     int to,w,nxt;  
     25 }e[maxn*2];//链式前向星建树 
     26 
     27 void init(){
     28     memset(head,-1,sizeof head);
     29     tot=0;
     30     id=0;
     31 }
     32 
     33 void add_edge(int u,int v,int w){  
     34     e[tot].to=v;
     35     e[tot].w=w;
     36     e[tot].nxt=head[u];
     37     head[u]=tot++;
     38 }
     39   
     40 void dfs(int u,int fa,int dep){
     41     ver[++id]=u;//第i个访问到的结点编号 
     42     depth[id]=dep;//第i个访问到的结点深度  
     43     first[u]=id;
     44     for(int i=head[u];i!=-1;i=e[i].nxt){
     45         int v=e[i].to;
     46         int w=e[i].w;
     47         if(v==fa) continue;
     48         dis[v]=dis[u]+w;//dis是先序遍历求 
     49         dfs(v,u,dep+1);
     50         ver[++id]=u;//后序遍历,再次访问父节点 
     51         depth[id]=dep;
     52     }
     53 }
     54 //int KT[maxn*2];
     55 void rmq_init(int n){
     56     //KT[1] = 0;
     57     //for(int i = 2; i <= n; i++)
     58     //    KT[i] = KT[i / 2] + 1;  
     59     int k=int(log(n)/log(2));
     60     for(int i=1;i<=n;++i)    rmq[i][0]=i;  
     61     for(int j=1;j<=k;++j){  
     62         for(int i=1;i+_pow[j]-1<=n;++i){//因为存的是索引 
     63             int a=rmq[i][j-1],b=rmq[i+_pow[j-1]][j-1];  
     64             rmq[i][j]=depth[a]<depth[b]?a:b;
     65         }
     66     }
     67 }
     68   
     69 int rmq_query(int l,int r){
     70     int k=int(log(r-l+1.0)/log(2.0));  
     71     int a=rmq[l][k],b=rmq[r-_pow[k]+1][k];  
     72     return depth[a]<depth[b]?a:b;
     73 }//返回的依然是索引 
     74   
     75 int LCA(int u,int v){
     76     int x=first[u],y=first[v];  
     77     if(x>y)swap(x,y);  
     78     int res=rmq_query(x,y);  
     79     return ver[res]; 
     80 }
     81 
     82 void init1(){
     83     for(int i=1;i<=n;i++) par[i]=i;
     84 }
     85 
     86 int find(int x){
     87     if(par[x]==x) return x;
     88     else return par[x]=find(par[x]);
     89 }
     90 
     91 void unite(int x,int y){
     92     x=find(x),y=find(y);
     93     if(x!=y) par[x]=y;
     94 }
     95 
     96 int main(){
     97     for(int i=0;i<maxm;++i)    _pow[i]=1<<i; //预处理2^n 
     98     int t,a,b,c,d;
     99     while(scanf("%d%d%d",&n,&m,&d)!=EOF){
    100         init();
    101         init1();
    102         for(int i=0;i<m;++i){
    103             a=read(),b=read(),c=read();
    104             add_edge(a,b,c);
    105             add_edge(b,a,c);
    106             unite(a,b);
    107         }
    108         for(int i=1;i<=n;i++){
    109             if(par[i]!=i) continue;
    110             dfs(i,-1,0);
    111         }
    112         rmq_init(2*n-1);
    113         for(int i=0;i<d;++i){
    114             a=read();b=read();
    115             if(find(a)!=find(b)){
    116                 printf("Not connected
    ");
    117                 continue;
    118             }
    119             int ans=LCA(a,b);
    120             printf("%lld
    ",dis[a]+dis[b]-2*dis[ans]);
    121         }
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    与DSP通信时,RD&WR信号
    4.2.1 Vector bit-select and part-select addressing
    数据校验
    数据结构 (树,图)
    ASOP编译说明
    os
    20180203-增与查
    yum安装MariaDB
    20180202之engine,URL,base,session
    列表
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7470532.html
Copyright © 2011-2022 走看看