• BZOJ——1602: [Usaco2008 Oct]牧场行走 || 洛谷—— P2912 [USACO08OCT]牧场散步Pasture Walking


    http://www.lydsy.com/JudgeOnline/problem.php?id=1602

    ||

    https://www.luogu.org/problem/show?pid=2912

    题目描述

    N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=Li<=10000)。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况,所以说这是一棵树。 这些奶牛是非常喜欢交际的,经常会去互相访问,他们想让你去帮助他们计算Q(1<=q<=1000)对奶牛之间的距离。

    输入

    *第一行:两个被空格隔开的整数:N和Q

     *第二行到第n行:第i+1行有两个被空格隔开的整数:AI,BI,LI

    *第n+1行到n+Q行:每一行有两个空格隔开的整数:P1,P2,表示两头奶牛的编号。

    输出

    *第1行到第Q行:每行输出一个数,表示那两头奶牛之间的距离。

    样例输入

    4 2
    2 1 2
    4 3 2
    1 4 3
    1 2
    3 2

    样例输出

    2
    7

    提示

     

    来源

    资格赛

    练习模板

    倍增:

     1 #include <algorithm>
     2 #include <cstdio>
     3  
     4 using namespace std;
     5  
     6 const int N(1000+15);
     7 int n,q,x,y,z;
     8 int dad[N<<1][23],deep[N<<1];
     9 int dis[N<<1];
    10 int sumedge,head[N<<1];
    11 struct Edge
    12 {
    13     int from,to,next,dis;
    14     Edge(int from=0,int to=0,int next=0,int dis=0) :
    15         from(from),to(to),next(next),dis(dis) {}
    16 }edge[N<<1];
    17  
    18 int add(int from,int to,int dis)
    19 {
    20     edge[++sumedge]=Edge(from,to,head[from],dis);
    21     return head[from]=sumedge;
    22 }
    23  
    24 void DFS(int x)
    25 {
    26     deep[x]=deep[dad[x][0]]+1;
    27     for(int i=0;dad[x][i];i++)
    28         dad[x][i+1]=dad[dad[x][i]][i];
    29     for(int i=head[x];i;i=edge[i].next)
    30         if(!deep[edge[i].to])
    31         {
    32             dad[edge[i].to][0]=x;
    33             dis[edge[i].to]=dis[x]+edge[i].dis;
    34             DFS(edge[i].to);
    35         }
    36 }
    37  
    38 int LCA(int x,int y)
    39 {
    40     if(deep[x]>deep[y]) swap(x,y);
    41     for(int i=20;i>=0;i--)
    42         if(deep[x]<=deep[dad[y][i]]) y=dad[y][i];
    43     if(x==y) return x;
    44     for(int i=20;i>=0;i--)
    45         if(dad[x][i]!=dad[y][i])
    46             x=dad[x][i],y=dad[y][i];
    47     return dad[x][0];
    48 }
    49  
    50 int main()
    51 {
    52     scanf("%d%d",&n,&q);
    53     for(int i=1;i<n;i++)
    54     {
    55         scanf("%d%d%d",&x,&y,&z);
    56         add(x,y,z); add(y,x,z);
    57     }
    58     DFS(1);
    59     for(;q;q--)
    60     {
    61         scanf("%d%d",&x,&y);
    62         printf("%d
    ",dis[x]+dis[y]-(dis[LCA(x,y)]<<1));
    63     }
    64     return 0;
    65 }

    然后是树剖的~

     1 #include <algorithm>
     2 #include <cstdio>
     3 #include <vector>
     4 
     5 using namespace std;
     6 
     7 const int N(1000+15);
     8 vector< pair<int,int> >vec[N];
     9 int n,q,x,y,z,dis[N];
    10 int dad[N],deep[N],size[N],top[N];
    11 
    12 void DFS(int x)
    13 {
    14     size[x]=1; deep[x]=deep[dad[x]]+1;
    15     for(int i=0;i<vec[x].size();i++)
    16         if(dad[x]!=vec[x][i].first)
    17         {
    18             dad[vec[x][i].first]=x;
    19             dis[vec[x][i].first]=dis[x]+vec[x][i].second;
    20             DFS(vec[x][i].first);
    21             size[x]+=size[vec[x][i].first];
    22         }
    23 }
    24 
    25 void DFS_(int x)
    26 {
    27     int t=0; if(!top[x]) top[x]=x;
    28     for(int i=0;i<vec[x].size();i++)
    29         if(dad[x]!=vec[x][i].first&&size[t]<size[vec[x][i].first]) t=vec[x][i].first;
    30     if(t) top[t]=top[x],DFS_(t);
    31     for(int i=0;i<vec[x].size();i++)
    32         if(dad[x]!=vec[x][i].first&&t!=vec[x][i].first) DFS_(vec[x][i].first);
    33 }
    34 
    35 int LCA(int x,int y)
    36 {
    37     while(top[x]!=top[y])
    38     {
    39         if(deep[top[x]]<deep[top[y]]) swap(x,y);
    40         x=dad[top[x]];
    41     }
    42     if(deep[x]>deep[y]) swap(x,y);
    43     return x;
    44 }
    45 
    46 int main()
    47 {
    48     scanf("%d%d",&n,&q);
    49     for(int i=1;i<n;i++)
    50     {
    51         scanf("%d%d%d",&x,&y,&z);
    52         vec[x].push_back(make_pair(y,z));
    53         vec[y].push_back(make_pair(x,z));
    54     }
    55     DFS(1); DFS_(1);
    56     for(;q;q--)
    57     {
    58         scanf("%d%d",&x,&y);
    59         printf("%d
    ",dis[x]+dis[y]-dis[LCA(x,y)]*2);
    60     }
    61     return 0;
    62 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    Eclispe造成的tomcat占用端口 无法启动 强制终止进程 转载
    JavaScript在页面中的执行顺序(理解声明式函数与赋值式函数) 转载
    spket IDE插件更新地址
    SQL 语句外键 a foreign key constraint fails
    面试技能树 转载
    简单粗暴 每个servlet之前都插入一段代码解决 乱码问题
    记录一个因sqlmap导致的错误
    Java与数据库数据类型对应表
    乐观锁与悲观锁
    maven打的包中含源文件jar包
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6817430.html
Copyright © 2020-2023  润新知