• Codevs 2370 小机房的树


    时间限制: 1 s  空间限制: 256000 KB   题目等级 : 钻石 Diamond
    题目描述 Description

    小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力

    输入描述 Input Description
    第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。
    第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点
    输出描述 Output Description

    一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。

    样例输入 Sample Input

    3

    1 0 1

    2 0 1

    3

    1 0

    2 0

    1 2

    样例输出 Sample Output

    1

    1

    2

    数据范围及提示 Data Size & Hint

    1<=n<=50000, 1<=m<=75000, 0<=c<=1000

    50分WA代码:

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<iostream>
     5 using namespace std;
     6 #define maxn 60010
     7 #define S 16
     8 int n,m,a[maxn],deep[maxn],fa[maxn][S+10],ans,p1,p2,head[maxn],num,dis[maxn];
     9 struct node{
    10     int u,v,pre,value;//  dis[i] 数组 从 i到根节点的最短距离 
    11 }e[maxn*2];
    12 void dfs(int u,int di)
    13 {
    14     dis[u]=di;/*统计u到根节点的距离*/
    15     for(int l=head[u];l;l=e[l].pre)
    16     {
    17         if(!deep[e[l].v])
    18         {
    19             deep[e[l].v]=deep[u]+1;/*处理孩子的深度*/
    20             fa[e[l].v][0]=u;/*初始化p数组*/
    21             dfs(e[l].v,di+e[l].value);
    22         }
    23     }
    24 }
    25 void get_fa()
    26 {
    27     for(int j=1;j<=S;j++)
    28         for(int i=1;i<=n;i++)
    29             fa[i][j]=fa[fa[i][j-1]][j-1];
    30 }
    31 int LCA(int a,int b)
    32 {
    33     if(deep[a]<deep[b])swap(a,b); 
    34     for(int j=S;j>=0;j--)
    35       if((deep[a]-(1<<j))>=deep[b])
    36         a=fa[a][j];
    37     if(a==b)return a;
    38     for(int i=S;i>=0;i--)
    39       if(fa[a][i]!=fa[b][i])
    40         {
    41           a=fa[a][i];
    42           b=fa[b][i];
    43         }
    44     return fa[a][0];
    45 }
    46 void add_egre(int from,int to,int value)
    47 {
    48     num++;
    49     e[num].u=from;
    50     e[num].v=to;
    51     e[num].value=value;
    52     e[num].pre=head[from];
    53     head[from]=num;
    54 }
    55 int main()
    56 {
    57     scanf("%d",&n);
    58     for(int i=1,x,y,z;i<n;i++)
    59     {
    60         scanf("%d%d%d",&x,&y,&z);
    61         add_egre(x,y,z);add_egre(y,x,z);
    62     }
    63     memset(dis,0,sizeof(dis));
    64     memset(deep,0,sizeof(deep));
    65     dfs(1,0);
    66     get_fa();scanf("%d",&m);
    67     for(int i=1;i<=m;i++)
    68     {
    69         scanf("%d%d",&p1,&p2);
    70         int k=LCA(p1,p2);
    71         ans=dis[p1]+dis[p2]-2*dis[k];// deep shendu
    72         printf("%d
    ",ans);
    73     }
    74     return 0;
    75 }

    赶脚思路没毛病~~~

    AC代码:

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<iostream>
     5 using namespace std;
     6 #define maxn 60010
     7 #define S 16
     8 int n,m,a[maxn],deep[maxn],fa[maxn][20],ans,p1,p2,head[maxn],num;long long dis[maxn];
     9 struct node{
    10     int u,v,pre,value;//  dis[i] 数组 从 i到根节点的最短距离 
    11 }e[maxn*4];
    12 void dfs(int u,long long di)
    13 {
    14     dis[u]=di;/*处理u到根节点的距离*/
    15     for(int l=head[u];l;l=e[l].pre)
    16     {
    17         if(!deep[e[l].v])
    18         {
    19             deep[e[l].v]=deep[u]+1;/*处理孩子的深度*/
    20             fa[e[l].v][0]=u;/*初始化fa数组*/
    21             dfs(e[l].v,di+e[l].value);
    22         }
    23     }
    24 }
    25 int LCA(int a,int b)
    26 {
    27     int i,j;
    28     if(deep[a]<deep[b]) swap(a,b); 
    29     for(i=0;(1<<i)<=deep[a];++i);
    30          i--;
    31     for(j=i;j>=0;j--)
    32       if((deep[a]-(1<<j))>=deep[b])
    33         a=fa[a][j];
    34     if(a==b)return a;
    35     for(j=i;j>=0;j--)
    36       if(fa[a][j]!=-1&&fa[a][j]!=fa[b][j])
    37         {
    38           a=fa[a][j];
    39           b=fa[b][j];
    40         }
    41     return fa[a][0];
    42 }
    43 void init()
    44 {
    45      int i,j;
    46      for(j=1;(1<<j)<n;j++)
    47        for(int i=0;i<n;++i)
    48         if(fa[i][j]=-1)
    49           fa[i][j]=fa[fa[i][j-1]][j-1];/*DP处理出i的所有2^j祖先是谁*/
    50 }
    51 void add_egre(int from,int to,int value)
    52 {
    53     num++;
    54     e[num].u=from;
    55     e[num].v=to;
    56     e[num].value=value;
    57     e[num].pre=head[from];
    58     head[from]=num;
    59 }
    60 int main()
    61 {
    62     scanf("%d",&n);
    63     for(int i=1,x,y,z;i<n;i++)
    64     {
    65         scanf("%d%d%d",&x,&y,&z);
    66         add_egre(x,y,z);add_egre(y,x,z);
    67     }
    68     memset(fa,-1,sizeof(fa));
    69     deep[0]=0;
    70     dfs(0,0);
    71     init(); 
    72     scanf("%d",&m);
    73     for(int i=1;i<=m;i++)
    74     {
    75         scanf("%d%d",&p1,&p2);
    76         int k=LCA(p1,p2);
    77         ans=dis[p1]+dis[p2]-2*dis[k];
    78         printf("%d
    ",ans);
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    用数据库表填充下拉列表框
    如何把存储过程查询出来的结果(记录)放到一个临时表里面
    关于vs2008设计视图假死的原因及解决方案总结
    关于vs2008新建App_Code文件夹
    给文本框添加灰色提示文字
    sql server 2005 怎么得到将要插入的数据的id
    下拉框绑定数据库后,如何在下拉框的最前面增加一项
    JS 获取页面传过来的参数值
    产品路线图规划可视化工具推荐
    Leangoo领歌scrum敏捷开发工具学习资料下载
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6103739.html
Copyright © 2020-2023  润新知