| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1476 人关注过本帖
标题:帮帮忙!一道有关最近公共祖先(LCA)的题目,我不会做。
只看楼主 加入收藏
brian1994
Rank: 2
来 自:广东省中山市一中
等 级:论坛游民
帖 子:63
专家分:47
注 册:2011-5-15
结帖率:75%
收藏
已结贴  问题点数:20 回复次数:6 
帮帮忙!一道有关最近公共祖先(LCA)的题目,我不会做。
【?】距离(distance)

Time Limit:1000MS  Memory Limit:65536K
 Total Submit:15 Accepted:7

Description

 【问题描述】
  给出n个点的一棵树,多次询问两点之间的最短距离。(边是双向的)

【输入格式】
  测试数据第一行为两个整数 N 和 M(1 < n≤10000, 0 < m≤20000)。 N表示点数,M表示询问次数。下来 n-1行,每行三个整数 x y k,表示点x和点y之间存在一条边长度为k( 0 < k≤100)。再接下来m行,每行两个整数 x y,表示询问点x到点y的最短距离。

【输出格式】
  输出m行。对于每次询问,输出一行。

Input

 2 2
1 2 100
1 2
2 1

Output

 100
100

Sample Input

3 2
1 2 10
3 1 15
1 2
3 2


Sample Output

10
25
搜索更多相关主题的帖子: 测试 distance Memory 
2011-09-20 13:13
brian1994
Rank: 2
来 自:广东省中山市一中
等 级:论坛游民
帖 子:63
专家分:47
注 册:2011-5-15
收藏
得分:0 
我不明白怎么建树
2011-09-20 17:08
brian1994
Rank: 2
来 自:广东省中山市一中
等 级:论坛游民
帖 子:63
专家分:47
注 册:2011-5-15
收藏
得分:0 
我知道怎么建树了,但是如何应用RMQ。。。
2011-09-21 14:27
无名可用
Rank: 4
等 级:业余侠客
帖 子:79
专家分:259
注 册:2010-7-27
收藏
得分:10 
我这有一个讲RMQ和LCA的空间,讲的不错,等回宿舍了发上来。我也只做过一道RMQ的题,LCA还没做。。
2011-09-22 09:32
无名可用
Rank: 4
等 级:业余侠客
帖 子:79
专家分:259
注 册:2010-7-27
收藏
得分:10 
http://community.(ST)_algorithm
希望对你有用
2011-09-22 10:03
brian1994
Rank: 2
来 自:广东省中山市一中
等 级:论坛游民
帖 子:63
专家分:47
注 册:2011-5-15
收藏
得分:0 
回复 5楼 无名可用
看不到。。。
2011-09-22 13:10
brian1994
Rank: 2
来 自:广东省中山市一中
等 级:论坛游民
帖 子:63
专家分:47
注 册:2011-5-15
收藏
得分:0 
测试数据过了,但是WRONG ANSEWER。错哪里了??
程序代码:
#include<iostream>
#include<cmath>
using namespace std;

const int maxn=10000+5;
int tol=0,n,m;
int map[maxn][maxn];
int f[maxn][3];
int deep[maxn]; //第i点在树中的深度 
int dist[maxn]; //第i点离树的根节点的距离
int p[maxn][15]; //第i点的2^j父亲

void init()
{
     cin>>n>>m;
     for (int i=1;i<n;i++)
     {
         int x,y,z;
         cin>>x>>y>>z;
         map[x][++map[x][0]]=y;
         map[y][++map[y][0]]=x;
         f[i][0]=x;f[i][1]=y;f[i][2]=z;
     }
}

void build(int x,int d)
{
     deep[x]=d++;//记录深度
     for (int i=1;i<=map[x][0];i++)
     {
         if (deep[map[x][i]]!=0) continue;
         p[map[x][i]][0]=x;
         for (int j=1;j<n;j++)
           if (f[j][0]==x && f[j][1]==map[x][i]
           || f[j][0]==map[x][i] && f[j][1]==x)
           {
              dist[map[x][i]]=dist[x]+f[j][2];
              break;
           }
         if (map[map[x][i]][0]==1) continue;
         build(map[x][i],d);
     } 
}

void tree()
{
     //设根节点为点1并建树
     dist[1]=0;
     build(1,1); 
}

void find()
{
     //预处理 
     for (int i=2;i<=n;i++)
     {
         for (int j=1;j<=n;j++)
         {
             int a=(int)pow(2,(double)j);
             if (a>deep[i]) break;
             p[i][j]=p[p[i][j-1]][j-1];
         }
     }
}

int solve(int x,int y)
{
    if (deep[x]>deep[y]) {int z=x; x=y; y=z;}
    
    int j=14;
    while (deep[x]<deep[y])
    {
          while (deep[y]-(1<<j)<deep[x]) j--;
          y=p[y][j];
    }
    
    j=14;
    while (x!=y)
    {
          while (j>0 && (deep[x]-(1<<j)<0 || p[x][j]==p[y][j])) j--;
          x=p[x][j];
          y=p[y][j];
    }
}

void doit()
{
     for (int i=1;i<=m;i++)
     {
         int x,y;
         cin>>x>>y;
         int com=solve(x,y);
         cout<<dist[x]-dist[com]+dist[y]-dist[com]<<endl;
     }
}

int main()
{
    init();
    tree();
    find();
    doit();
    return 0;   
}

2011-09-22 15:55
快速回复:帮帮忙!一道有关最近公共祖先(LCA)的题目,我不会做。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016044 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved