zoukankan      html  css  js  c++  java
  • lca 例题 WK

    codevs2370 小机房的树

     1 #include<iostream>
     2 #include<cstdio>
     3 #define maxn 110000
     4 using namespace std;
     5 int head[maxn],deep[maxn],sum[maxn][22],f[maxn][22];
     6 int n,m,num,ans;
     7 struct node{
     8     int to,v,pre;
     9 }e[maxn];
    10 void Insert(int from,int to,int v){
    11     e[++num].to=to;
    12     e[num].v=v;
    13     e[num].pre=head[from];
    14     head[from]=num;
    15 }
    16 void find_deep(int from,int now,int dep,int val){
    17     deep[now]=dep;f[now][0]=from;sum[now][0]=val;
    18     for(int i=head[now];i;i=e[i].pre){
    19         int v=e[i].to;
    20         if(v!=from)find_deep(now,v,dep+1,e[i].v);
    21     }
    22 }
    23 void find_father(){
    24     for(int i=1;i<=21;i++)
    25         for(int j=1;j<=n;j++)
    26             f[j][i]=f[f[j][i-1]][i-1];
    27     for(int i=1;i<=21;i++)
    28         for(int j=1;j<=n;j++)
    29             sum[j][i]=sum[f[j][i-1]][i-1]+sum[j][i-1];
    30 }
    31 int get(int a,int delta){
    32     for(int i=0;i<=21;i++){
    33         if(delta&(1<<i))ans+=sum[a][i],a=f[a][i];
    34     }
    35     return a;
    36 }
    37 int lca(int a,int b){
    38     if(deep[a]<deep[b])swap(a,b);
    39     if(a==b)return 0;
    40     a=get(a,deep[a]-deep[b]);
    41     for(int i=21;i>=0;i--){
    42         if(f[a][i]!=f[b][i]){
    43             ans+=sum[a][i]+sum[b][i];
    44             a=f[a][i];b=f[b][i];
    45         }
    46     }
    47     if(a!=b)ans+=sum[a][0]+sum[b][0];
    48 }
    49 int main(){
    50     scanf("%d",&n);
    51     int x,y,z;
    52     for(int i=1;i<n;i++){
    53         scanf("%d%d%d",&x,&y,&z);
    54         Insert(x+1,y+1,z);
    55         Insert(y+1,x+1,z);
    56     }
    57     find_deep(1,1,0,0);
    58     find_father();
    59     scanf("%d",&m);
    60     for(int i=1;i<=m;i++){
    61         scanf("%d%d",&x,&y);
    62         ans=0;lca(x+1,y+1);
    63         printf("%d
    ",ans);
    64     }
    65 }
    View Code

    cogs1439. [NOIP2013]货车运输

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 #define maxn 10010
     8 #define maxm 50010
     9 int n,m,f[maxn][20],sum[maxn][20],fa[maxn],num,p,dep[maxn],head[maxn]; 
    10 bool vis[maxn];
    11 struct node{
    12     int f,to,v;
    13 }a[maxm];
    14 struct Edge{
    15     int pre,v,to;
    16 }e[maxm];
    17 int cmp(node x,node y){return x.v>y.v;}
    18 int find(int x){
    19     if(fa[x]==x)return fa[x];
    20     else return fa[x]=find(fa[x]);
    21 }
    22 int connect(int x,int y){
    23     int f1=find(x),f2=find(y);
    24     if(f1==f2)return 0;
    25     else fa[f1]=f2;return 1;
    26 }
    27 void Insert(int from,int to,int v){
    28     e[++num].v=v;
    29     e[num].to=to;
    30     e[num].pre=head[from];
    31     head[from]=num;
    32 }
    33 void dfs(int now,int father,int deep){
    34     vis[now]=1;
    35     dep[now]=deep;
    36     for(int i=head[now];i;i=e[i].pre){
    37         int v=e[i].to;
    38         if(v==father)continue;
    39         f[v][0]=now;
    40         sum[v][0]=e[i].v;
    41         dfs(v,now,deep+1);
    42     }
    43 }
    44 int lca(int x,int y){
    45     if(x==y)return 0;
    46     int ans=0x3f3f3f3f;
    47     if(dep[x]<dep[y])swap(x,y);
    48     for(int i=18;i>=0;i--){
    49         if(dep[f[x][i]]>=dep[y]&&f[x][i]!=0)ans=min(ans,sum[x][i]),x=f[x][i];
    50     }
    51     if(x==y)return ans;
    52     for(int i=18;i>=0;i--){
    53         if(f[x][i]!=f[y][i]){
    54             ans=min(ans,sum[x][i]);
    55             ans=min(ans,sum[y][i]);
    56             x=f[x][i];y=f[y][i];
    57         }
    58     }
    59     ans=min(sum[x][0],ans);ans=min(sum[y][0],ans);
    60     return ans;
    61 }
    62 int main(){
    63     //freopen("Cola.txt","r",stdin);
    64     freopen("truck.in","r",stdin);
    65     freopen("truck.out","w",stdout);
    66     memset(sum,127/3,sizeof(sum));
    67     int x,y,z;
    68     scanf("%d%d",&n,&m);
    69     for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].f,&a[i].to,&a[i].v);
    70     for(int i=1;i<=n;i++)fa[i]=i;
    71     sort(a+1,a+m+1,cmp);int cnt=0;
    72     for(int i=1;i<=m;i++){
    73         if(connect(a[i].f,a[i].to)){
    74             Insert(a[i].f,a[i].to,a[i].v);
    75             Insert(a[i].to,a[i].f,a[i].v);
    76             cnt++;if(cnt==n-1)break;
    77         }
    78     }
    79     for(int i=1;i<=n;i++)if(!vis[i])dfs(i,0,1);
    80     for(int j=1;(1<<j)<=n;j++)
    81         for(int i=1;i<=n;i++)
    82             if(f[f[i][j-1]][j-1]!=0){
    83                 f[i][j]=f[f[i][j-1]][j-1];
    84                 sum[i][j]=min(sum[i][j-1],sum[f[i][j-1]][j-1]);
    85             }
    86     scanf("%d",&p);
    87     for(int i=1;i<=p;i++){
    88         scanf("%d%d",&x,&y);
    89         if(find(x)!=find(y)){printf("-1
    ");continue;}
    90         printf("%d
    ",lca(x,y));
    91     }
    92 }
    View Code

    hdu2586

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <vector>
     5 using namespace std;
     6 vector<int> v[41000];
     7 vector<int> w[41000];
     8 int f[41000][21];//f[i][j]表示i点向上2^j层的祖先 
     9 int sum[41000][21];//g[i][j]表示i点到从i向上2^j层的祖先的距离 
    10 int dep[41000];
    11 int n,m;
    12 void dfs(int pos,int pre,int depth)
    13 {
    14     dep[pos]=depth;
    15     for(int i=0;i<v[pos].size();i++)
    16     {
    17         int t=v[pos][i];
    18         if(t==pre) continue;
    19         f[t][0]=pos;
    20         sum[t][0]=w[pos][i];
    21         dfs(t,pos,depth+1);
    22     }
    23 }
    24 int query(int a,int b)
    25 {
    26     int Sum=0;
    27     if(dep[a]<dep[b]) swap(a,b);//深度较深的点 
    28     for(int i=20;i>=0;i--)//找到a在深度dep[b]处的祖先 
    29     {
    30         if(dep[f[a][i]]>=dep[b])
    31         {
    32             Sum+=sum[a][i];//a到该祖先的距离 
    33             a=f[a][i];
    34         }
    35     }
    36     if(a==b) return Sum;//挪到相同深度后如果在同一点直接return 
    37     int x;
    38     for(int i=20;i>=0;i--)//否则a和b一起往上跳 
    39     {
    40         if(f[a][i]!=f[b][i])
    41         {
    42             Sum+=sum[a][i];
    43             a=f[a][i];
    44             Sum+=sum[b][i];
    45             b=f[b][i];
    46         }
    47     }
    48     return Sum+sum[a][0]+sum[b][0];//最后跳到最近公共祖先的下一层,所以要再加上上一层 
    49 }
    50 int main()
    51 {
    52     int T;
    53     cin>>T;
    54     while(T--)
    55     {
    56         scanf("%d%d",&n,&m);
    57         memset(dep,-1,sizeof(dep));
    58         memset(f,0,sizeof(f));
    59         memset(sum,0,sizeof(sum));
    60         for(int i=0;i<n;i++)//md
    61             v[i].clear(),w[i].clear();
    62         for(int i=1;i<n;i++)
    63         {
    64             int x,y,c;
    65             cin>>x>>y>>c;
    66             v[x].push_back(y);
    67             w[x].push_back(c);
    68             v[y].push_back(x);
    69             w[y].push_back(c);
    70         }
    71         int xxx=v[1].size();
    72         dfs(1,0,1);//dfs处理出每个点的深度,以及各种... 
    73     
    74         for(int i=1;1<<i<=n;i++)
    75             for(int j=1;j<=n;j++)
    76                 f[j][i]=f[f[j][i-1]][i-1],
    77                 sum[j][i]=sum[f[j][i-1]][i-1]+sum[j][i-1];
    78         for(int i=1;i<=m;i++)
    79         {
    80             int x,y;
    81             cin>>x>>y;
    82             if(x==y) cout<<"0"<<endl;
    83             else cout<<query(x,y)<<endl;
    84         }
    85     }
    86     return 0;
    87 }
    View Code

    洛谷3379

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 #define maxn 500010
     5 int n,m,s,f[maxn][22],deep[maxn],head[maxn],num;
     6 struct node{
     7     int to,pre;
     8 }e[maxn<<1];
     9 int qread(){
    10     int x=0,j=1;
    11     char ch=getchar();
    12     while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
    13     while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
    14     return x*j;
    15 }
    16 void Insert(int from,int to){
    17     e[++num].to=to;
    18     e[num].pre=head[from];
    19     head[from]=num;
    20 }
    21 void find_deep(int from,int now,int dep){
    22     f[now][0]=from;deep[now]=dep;
    23     for(int i=head[now];i;i=e[i].pre){
    24         int v=e[i].to;
    25         if(v!=from){
    26             find_deep(now,v,dep+1);
    27         }
    28     }
    29 }
    30 void find_father(){
    31     for(int j=1;j<=21;j++)
    32         for(int i=1;i<=n;i++)
    33             f[i][j]=f[f[i][j-1]][j-1];
    34 }
    35 int get(int a,int delta){
    36     for(int i=0;i<=21;i++){
    37         if(delta&(1<<i))a=f[a][i];
    38     }return a;
    39 }
    40 int lca(int a,int b){
    41     if(deep[a]<deep[b])swap(a,b);
    42     a=get(a,deep[a]-deep[b]);
    43     if(a==b) return a;
    44     for(int i=21;i>=0;i--){
    45         if(f[a][i]!=f[b][i]){
    46             a=f[a][i],b=f[b][i];
    47         }
    48     }
    49     return f[a][0];
    50 }
    51 int main(){
    52     n=qread(),m=qread(),s=qread();
    53     int x,y;
    54     for(int i=1;i<=n-1;i++){
    55         x=qread();y=qread();
    56         Insert(x,y);
    57         Insert(y,x);
    58     }
    59     find_deep(s,s,0);
    60     find_father();
    61     for(int i=1;i<=m;i++){
    62         x=qread();y=qread();
    63         int ans=lca(x,y);
    64         printf("%d
    ",ans);
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    下载Instagram的图片
    golang写一个简单的爬虫
    [转载]Go的50度灰:Golang新开发者要注意的陷阱和常见错误
    无法获得锁 /var/lib/dpkg/lock
    RouterOS 设定NAT loopback (Hairpin NAT)回流
    Fix-Dell iDRAC 7 error: RAC0218: The maximum number of user sessions is reached
    Nginx Location配置总结
    vcenter6.7将ESXI所有的端口组迁移到分布式交换机的步骤
    什么是DSCP,如何使用DSCP标记搭配ROS策略
    MTR追踪的好工具
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/6883145.html
Copyright © 2011-2022 走看看