zoukankan      html  css  js  c++  java
  • poj 1986 Distance Queries(LCA:倍增/离线)

    计算树上的路径长度。input要去查poj 1984。

    任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离。输出d[u]+d[v]-2*d[lca(u,v)]。

    倍增求解:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<algorithm>
      5 #define rep(i,a,b) for(int i=a;i<=b;i++)
      6 #define clr(a,m) memset(a,m,sizeof(a))
      7 using namespace std;
      8 
      9 const int MAXN=44444;
     10 const int POW = 18;
     11 
     12 struct Edge{
     13     int v,next,c;
     14     Edge(){}
     15     Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
     16 }edge[MAXN<<1];
     17 
     18 int head[MAXN],tol;
     19 int p[MAXN][POW],d[MAXN];
     20 int vis[MAXN],dis[MAXN];
     21 queue<int>q;
     22 
     23 void init()
     24 {
     25     tol=0;
     26     clr(head,-1);
     27 }
     28 
     29 void add(int u,int v,int c)
     30 {
     31     edge[tol]=Edge(v,c,head[u]);
     32     head[u]=tol++;
     33 }
     34 
     35 void bfs(int x)
     36 {
     37     clr(vis,0);
     38     clr(dis,0);
     39     while(!q.empty())
     40         q.pop();
     41     q.push(x);
     42     vis[x]=1;
     43     dis[x]=0;
     44     while(!q.empty())
     45     {
     46         int u=q.front();
     47         q.pop();
     48         for(int i=head[u];i!=-1;i=edge[i].next)
     49         {
     50             int v=edge[i].v;
     51             if(vis[v])
     52                 continue;
     53             q.push(v);
     54             vis[v]=1;
     55             dis[v]=dis[u]+edge[i].c;
     56         }
     57     }
     58 }
     59 
     60 void dfs(int u,int fa){
     61     d[u]=d[fa]+1;
     62     p[u][0]=fa;
     63     for(int i=1;i<POW;i++) p[u][i]=p[p[u][i-1]][i-1];
     64     for(int i=head[u];i!=-1;i=edge[i].next){
     65         int v=edge[i].v;
     66         if(v==fa) continue;
     67         dfs(v,u);
     68     }
     69 }
     70 
     71 int lca( int a, int b ){
     72     if( d[a] > d[b] ) a ^= b, b ^= a, a ^= b;
     73     if( d[a] < d[b] ){
     74         int del = d[b] - d[a];
     75         for( int i = 0; i < POW; i++ ) if(del&(1<<i)) b=p[b][i];
     76     }
     77     if( a != b ){
     78         for( int i = POW-1; i >= 0; i-- )
     79             if( p[a][i] != p[b][i] )
     80                  a = p[a][i] , b = p[b][i];
     81         a = p[a][0], b = p[b][0];
     82     }
     83     return a;
     84 }
     85 
     86 void LCA(int n)
     87 {
     88     clr(p,0);
     89     d[1]=0;
     90     dfs(1,1);
     91 
     92     bfs(1);
     93 
     94     int k;
     95     scanf("%d",&k);
     96     int u,v;
     97     rep(i,1,k){
     98         scanf("%d%d",&u,&v);
     99         printf("%d
    ",dis[u]+dis[v]-2*dis[lca(u,v)]);
    100     }
    101 }
    102 
    103 int main()
    104 {
    105     int n,m;
    106     scanf("%d%d",&n,&m);
    107     init();
    108     rep(i,1,m){
    109         int u,v,c;
    110         scanf("%d%d%d%*s",&u,&v,&c);
    111         add(u,v,c);
    112         add(v,u,c);
    113     }
    114 
    115     LCA(n);
    116     return 0;
    117 }
    View Code

     又用tarjin离线做了一遍= =

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<algorithm>
      5 #define rep(i,a,b) for(int i=a;i<=b;i++)
      6 #define clr(a,m) memset(a,m,sizeof(a))
      7 using namespace std;
      8 
      9 const int MAXN=44444;
     10 
     11 struct Edge{
     12     int v,next,c;
     13     Edge(){}
     14     Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
     15 }edge[MAXN<<1];
     16 
     17 struct EDGE{
     18     int u,v;
     19     int ans;
     20     EDGE(){}
     21     EDGE(int _u,int _v):u(_u),v(_v),ans(-1){}
     22 };
     23 
     24 int head[MAXN],tol;
     25 int p[MAXN],vis[MAXN],dis[MAXN];
     26 
     27 queue<int>q;
     28 vector<int>query[MAXN];
     29 vector<EDGE>G;
     30 
     31 void init()
     32 {
     33     tol=0;
     34     clr(head,-1);
     35 }
     36 
     37 void add(int u,int v,int c)
     38 {
     39     edge[tol]=Edge(v,c,head[u]);
     40     head[u]=tol++;
     41 }
     42 
     43 void build(int m)
     44 {
     45     init();
     46     rep(i,1,m){
     47         int u,v,c;
     48         scanf("%d%d%d%*s",&u,&v,&c);
     49         add(u,v,c);
     50         add(v,u,c);
     51     }
     52 
     53     int k;
     54     scanf("%d",&k);
     55     rep(i,1,k){
     56         int u,v,siz;
     57         scanf("%d%d",&u,&v);
     58 
     59         G.push_back(EDGE(u,v));
     60         siz=G.size();
     61         query[u].push_back(siz-1);
     62 
     63         G.push_back(EDGE(v,u));
     64         siz=G.size();
     65         query[v].push_back(siz-1);
     66     }
     67 }
     68 
     69 void bfs(int x)
     70 {
     71     clr(vis,0);
     72     clr(dis,0);
     73     while(!q.empty())
     74         q.pop();
     75     q.push(x);
     76     vis[x]=1;
     77     dis[x]=0;
     78     while(!q.empty())
     79     {
     80         int u=q.front();
     81         q.pop();
     82         for(int i=head[u];i!=-1;i=edge[i].next)
     83         {
     84             int v=edge[i].v;
     85             if(vis[v])
     86                 continue;
     87             q.push(v);
     88             vis[v]=1;
     89             dis[v]=dis[u]+edge[i].c;
     90         }
     91     }
     92 }
     93 
     94 int find(int x)
     95 {
     96     return (x==p[x])?x:(p[x]=find(p[x]));
     97 }
     98 
     99 void dfs(int x)
    100 {
    101     vis[x]=1;
    102     for(int i=head[x];i!=-1;i=edge[i].next)
    103     {
    104         int v=edge[i].v;
    105         if(vis[v])
    106             continue;
    107         dfs(v);
    108         p[v]=x;
    109     }
    110 
    111     int siz =query[x].size()-1;
    112     rep(i,0,siz)
    113     {
    114         int t=query[x][i];
    115         if(vis[G[t].v]){
    116             G[t].ans=find(G[t].v);
    117         }
    118     }
    119 }
    120 
    121 void LCA(int rt,int n)
    122 {
    123     clr(vis,0);
    124     rep(i,1,n)
    125         p[i]=i;
    126     dfs(rt);
    127 }
    128 
    129 void PRT()
    130 {
    131     int siz=G.size();
    132     for(int i=0;i<siz;i+=2)
    133     {
    134         int u=G[i].u;
    135         int v=G[i].v;
    136         if(G[i].ans!=-1)
    137             printf("%d
    ",dis[u]+dis[v]-2*dis[G[i].ans]);
    138         else
    139             printf("%d
    ",dis[u]+dis[v]-2*dis[G[i^1].ans]);
    140     }
    141 }
    142 
    143 int main()
    144 {
    145     int n,m;
    146     scanf("%d%d",&n,&m);
    147     build(m);
    148     bfs(1);
    149     LCA(1,n);
    150     PRT();
    151     return 0;
    152 }
    View Code
  • 相关阅读:
    Shell脚本 --- 正则表达式和文本处理工具
    python的eval、exec函数
    内置函数 Built-in Functions
    关于Python中的lambda
    Python中*args和**kwargs的区别
    Python基础-10-文件操作
    Python基础-09-内置函数
    Python基础-08-函数
    Python基础-07-集合
    Python基础-06-字典
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3258924.html
Copyright © 2011-2022 走看看