POJ-1330(LCA算法之RMQ)

来源:互联网 发布:电脑主题壁纸软件 编辑:程序博客网 时间:2024/05/22 00:21

题解思路:直接LCA算法套模板
题目链接

#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<cmath>#include<algorithm>using namespace std;const int mx = 1e4+10;int dp[2*mx][18];int first[2*mx]; //该节点第一次出现的位置int ver[2*mx];  //该位置的编号int deep[2*mx]; //树节点的深度vector<int>v[mx];int tot;bool vis[mx];void dfs(int u,int Deep){    ver[++tot] = u,deep[tot] = Deep,first[u] = tot;    vis[u] = 1;    for(int i = 0; i < v[u].size(); i++){        int d = v[u][i];        if(!vis[d]){            dfs(d,Deep+1);            ver[++tot] = u;            deep[tot] = Deep;        }    }}void st(){    for(int i = 1; i <= tot; i++)        dp[i][0] = i;    for(int j = 1; (1<<j) <= tot; j++){        int d = (1<<j);        for(int i = 1; i+d-1 <= tot; i++)            dp[i][j] = deep[dp[i][j-1]]<deep[dp[i+d/2][j-1]]?dp[i][j-1]:dp[i+d/2][j-1];    }}int rmq(int l,int r){    if(l > r)        swap(l,r);    int k = log(r-l+1.0)/log(2.0);    r = r-(1<<k)+1;    int a = deep[dp[l][k]];    int b = deep[dp[r][k]];    return a<b?dp[l][k]:dp[r][k];}int main(){    int t;    int n;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        tot = 0;        memset(vis,0,sizeof(vis));        for(int i = 1; i <= n; i++)            v[i].clear();        for(int i = 1; i < n; i++){            int x,y;            scanf("%d%d",&x,&y);            vis[y] = 1;            v[x].push_back(y);        }        int flag = 0;        for(int i = 1; i <= n; i++)            if(!vis[i]){                memset(vis,0,sizeof(vis));                dfs(i,1);                break;            }        st();        int x,y;        scanf("%d%d",&x,&y);        x = first[x];        y = first[y];        printf("%d\n",ver[rmq(x,y)]);    }    return 0;}
原创粉丝点击