RMQ && LCA

//这里lca是要开两倍空间的!!不然显示超时。。。。
//因为RMQ&&LCA与郭华阳论文中不太一样,但思想是一样的
         1(1)                                      1
       /      \                                /      |   \
      2(2)     3(5)                       2       3    4
      /   \        \                         /  \
   4(3)  5(4)     6(6)                 5   6
 tot :1 2 3 4 5 6 7 8 9 10 11
 num :1 2 4 2 5 2 1 3 6  3  1(遍历 过程中节点的值)
 F[] :1 2 4 5 3 6
 B[] :1 2 3 2 4 2 1 5 6  5  1  深搜的路径中记录的时间戳(小括号内)
 pos :1 2 8 3 5 9   各个点第一次出现的位置
 比如要求5 6 的最近公共祖先
 先求B[pos[5]]-->B[pos[6]]之间的最小值x,代表最小的时间戳
 然后F[x]即为最近公共祖先
 简单证明:
 时间戳的记录遵循深度优先原则,在深搜过程中从a点到b点的路径中可能会经过最近
 公共祖先多次,也就是说深搜路径中可能会有多个最小的时间戳,但它们都是同一个
 点,即最近公共祖先,如上右图中5和4的最近公共祖先1

View Code
 1 #include<string.h>
2 #include<stdio.h>
3 #include<vector>
4 #include<math.h>
5 using namespace std;
6 const int M =1010;
7 const double inf = 1e20;
8 int min(int a,int b){return a<b?a:b;}
9 double max(double a,double b){return a>b?a:b;}
10 int n,k,tdfn,tot;
11 int dp[20][2*M],vis[M];
12 int B[2*M],LOG[2*M],used[M],F[2*M],pos[M];
13 vector<int> edge[M];
14 void rmq_init(int n,int num[])
15 {
16 int i,j;
17 for(j=1;j<=n;j++)
18 dp[0][j]=num[j];
19 for(j=1;j<=LOG[n];j++)
20 {
21 int limit=n+1-(1<<j);
22 for(i=1;i<=limit;i++)
23 {
24 int x=i+(1<<j>>1);
25 dp[j][i]=min(dp[j-1][x],dp[j-1][i]);
26 }
27 }
28 }
29 int rmq(int l,int r,int num[])
30 {
31 int m=LOG[r-l+1];
32 return min(dp[m][l],dp[m][r-(1<<m)+1]);
33 }
34 void dfs(int s)
35 {
36 int i,t;
37 used[s]=1;
38 int tmp=++tdfn;
39 B[++tot]=tmp;F[tmp]=s;
40 pos[s]=tot;
41 for(i=0;i<edge[s].size();i++)
42 {
43 t=edge[s][i];
44 if(used[t]) continue;
45 dfs(t);
46 B[++tot]=tmp;//backtrack
47 }
48 }
49 int lca(int a,int b)
50 {
51 if(pos[a]>pos[b])
52 {
53 int tmp=a;
54 a=b;
55 b=tmp;
56 }
57 int ans=rmq(pos[a],pos[b],B);
58 return F[ans];
59 }
60 int main()
61 {
62 LOG[0]=-1;
63 for(i=1;i<2*M;i++)
64 LOG[i]=LOG[i>>1]+1;
65 //建图
66 tdfn=0;
67 tot=0;
68 memset(used,0,sizeof(used));
69 dfs(1);
70 rmq_init(tot,B);
71 return 0;
72 }



posted @ 2011-10-27 13:08  Because Of You  Views(449)  Comments(0Edit  收藏  举报