• CODEVS 2370 小机房的树


    传送门:Problem 2370

    https://www.cnblogs.com/violet-acmer/p/9686774.html

    AC代码:

    Tarjan+LCA:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define pb(x) push_back(x)
     7 const int maxn=5e4+50;
     8 
     9 int n,q;
    10 int fa[maxn];
    11 int dist[maxn];
    12 bool vis[maxn];
    13 int res[75050];
    14 struct Node
    15 {
    16     int to;
    17     int weight;
    18     Node(int to,int weight):to(to),weight(weight){}
    19 };
    20 vector<Node >edge[maxn],query[maxn];
    21 void addEdge(int u,int v,int w)
    22 {
    23     edge[u].pb(Node(v,w));
    24     edge[v].pb(Node(u,w));
    25 }
    26 void addQuqry(int u,int v,int id)
    27 {
    28     query[u].pb(Node(v,id));
    29     query[v].pb(Node(u,id));
    30 }
    31 
    32 //===========LCA================
    33 int Find(int x)
    34 {
    35     return x == fa[x] ? x:fa[x]=Find(fa[x]);
    36 }
    37 void Dfs(int v,int f,int l)
    38 {
    39     fa[v]=v;
    40     dist[v]=l;
    41     vis[v]=true;
    42     for(int i=0;i < edge[v].size();i++)
    43     {
    44         int to=edge[v][i].to;
    45         int w=edge[v][i].weight;
    46         if(to != f)
    47         {
    48             Dfs(to,v,l+w);
    49             fa[to]=v;
    50         }
    51     }
    52     for(int i=0;i < query[v].size();i++)
    53     {
    54         int to=query[v][i].to;
    55         int id=query[v][i].weight;
    56         if(vis[to])
    57             res[id]=dist[to]-dist[Find(to)]+dist[v]-dist[Find(to)];
    58     }
    59 }
    60 void Tarjan()
    61 {
    62     for(int i=1;i <= n;++i)
    63         if(!vis[i])
    64             Dfs(i,i,0);
    65 }
    66 //==============================
    67 //==============================
    68 void Init()
    69 {
    70     memset(vis,false,sizeof vis);
    71     memset(res,-1,sizeof res);
    72     for(int i=1;i <= n;++i)
    73         edge[i].clear(),query[i].clear();
    74 }
    75 int main()
    76 {
    77     Init();
    78     scanf("%d",&n);
    79     for(int i=1;i < n;++i)
    80     {
    81         int u,v,w;
    82         scanf("%d%d%d",&u,&v,&w);
    83         addEdge(u,v,w);
    84     }
    85     scanf("%d",&q);
    86     for(int i=1;i <= q;++i)
    87     {
    88         int u,v;
    89         scanf("%d%d",&u,&v);
    90         addQuqry(u,v,i);
    91     }
    92     Tarjan();
    93     for(int i=1;i <= q;++i)
    94         printf("%d
    ",res[i]);
    95 }
    View Code

    二分+LCA:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define pb(x) push_back(x)
     7 const int maxn=5e4+50;
     8 
     9 int n,q;
    10 int fa[20][maxn];
    11 int dist[maxn];
    12 int depth[maxn];
    13 struct Node
    14 {
    15     int to;
    16     int w;
    17     Node(int to,int w):to(to),w(w){}
    18 };
    19 vector<Node >edge[maxn];
    20 void addEdge(int u,int v,int w)
    21 {
    22     edge[u].pb(Node(v,w));
    23     edge[v].pb(Node(u,w));
    24 }
    25 //==============LCA============
    26 void Dfs(int v,int f,int d,int l)
    27 {
    28     depth[v]=d;
    29     dist[v]=l;
    30     fa[0][v]=f;
    31     for(int i=0;i < edge[v].size();i++)
    32     {
    33         int to=edge[v][i].to;
    34         int w=edge[v][i].w;
    35         if(to != f)
    36             Dfs(to,v,d+1,l+w);
    37     }
    38 }
    39 int LCA(int u,int v)//it faster than the method in book
    40 {
    41     if(depth[u] > depth[v])
    42         swap(u,v);//guarantee depth[v] > depth[u]
    43     int i;
    44     for(i=0;(1<<i) <= depth[v];i++);//find the max k that v can <<
    45     i--;
    46     for(int k=i;k >= 0;--k)
    47         if((depth[v]-(1<<k)) >= depth[u])
    48            v=fa[k][v];
    49     if(v == u)
    50         return v;
    51     for(int k=i;k >= 0;--k)
    52         if(fa[k][v] != -1 && fa[k][v] != fa[k][u])
    53         {
    54             u=fa[k][u];
    55             v=fa[k][v];
    56         }
    57     return fa[0][v];
    58 }
    59 void Pretreat()
    60 {
    61     for(int i=1;i <= n;++i)
    62         if(!depth[i])
    63             Dfs(i,-1,0,0);
    64     for(int k=0;k+1 < 20;k++)
    65         for(int v=1;v <= n;++v)
    66             if(fa[k][v] == -1)
    67                 fa[k+1][v]=-1;
    68             else
    69                 fa[k+1][v]=fa[k][fa[k][v]];
    70 }
    71 //=============================
    72 void Init()
    73 {
    74     memset(depth,0,sizeof(depth));
    75 }
    76 int main()
    77 {
    78     Init();
    79     scanf("%d",&n);
    80     for(int i=1;i < n;i++)
    81     {
    82         int u,v,w;
    83         scanf("%d%d%d",&u,&v,&w);
    84         addEdge(u,v,w);
    85     }
    86     Pretreat();
    87     scanf("%d",&q);
    88     for(int i=1;i <= q;++i)
    89     {
    90         int u,v;
    91         scanf("%d%d",&u,&v);
    92         int lca=LCA(u,v);
    93         printf("%d
    ",dist[u]+dist[v]-2*dist[lca]);
    94     }
    95 }
    View Code
  • 相关阅读:
    connect: network is unreachable问题的解决
    Linux图形界面与字符界面切换
    Xshell远程连接Linux服务器出错
    demo-placeholder兼容ie8
    Python设计TFTP客户端
    python hashlib、hmac模块
    python time、datetime、random、os、sys模块
    python 字符串和字典
    ssh远程登录时提示access denied
    指针的指针与指针的引用
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/9694775.html
Copyright © 2020-2023  润新知