码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3078

时间:2014-12-14 09:29:40      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:lca   图论   rmq   

求路径中权重最小的点

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
#define N 80010

int vis[N],mark[N],first[N],ver[N*2];
int val[N];
int dis[N];
int deep[N*2];
int _pow[30];
int par[N];
int ans[N];
int dp[2*N][25];
vector<int >mp[N];
int n,m;
int tot;
int cnt;

void init (){
    for(int i=1;i<=n;i++){
    mp[i].clear();
    }
    for(int i=0;i<25;i++)
    _pow[i]=(1<<i);
    memset(first,0,sizeof(first));
    memset(ver,0,sizeof(ver));
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(deep,0,sizeof(deep));
    memset(par,0,sizeof(par));

}

void dfs(int u,int dep){
    vis[u]=1;
    ver[++tot]=u;
    first[u]=tot;
    deep[tot]=dep;
    for(int i=0;i<mp[u].size();i++){
    int v =mp[u][i];
    if(vis[v])continue;
    par[v]=u;
    dfs(v,dep+1);
    ver[++tot]=u;
    deep[tot]=dep;
    }
}

void ST(int len){
    int K = (int)(log((double)len) / log(2.0));
    for(int i=1; i<=len; i++) dp[i][0] = i;
    for(int j=1; j<=K; j++)
        for(int i=1; i+_pow[j]-1<=len; i++)
        {
            int a = dp[i][j-1] , b = dp[i+_pow[j-1]][j-1];
            if(deep[a] < deep[b]) dp[i][j] = a;
            else            dp[i][j] = b;
        }
}

int RMQ(int x ,int y)
{
    int K = (int)(log((double)(y-x+1)) / log(2.0));
    int a = dp[x][K] , b = dp[y-_pow[K]+1][K];
    if(deep[a] < deep[b]) return a;
    else            return b;
}

int LCA(int u ,int v)
{
    int x = first[u] , y = first[v];
    if(x > y) swap(x,y);
    int res = RMQ(x,y);
    return ver[res];
}

void findpar(int u,int fa){
    //printf("%d  fa=%d\n",u,fa);
    while(u!=fa){
    ans[cnt++]=dis[u];
    u=par[u];
    }
    ans[cnt++]=dis[fa];
}

bool cmp(int x,int y){
   return x>y;
}

int main(){
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=n;i++)
    scanf("%d",&dis[i]);
    for(int i=1;i<n;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    mp[a].push_back(b);
    mp[b].push_back(a);
    }
    tot=0;
    par[1]=0;
    dfs(1,1);
   // printf("%d\n",tot);
    //for(int i=1;i<=n;i++)
   // printf("par[%d]===%d\n",i,par[i]);
    ST(tot);
    while(m--){
    int t,a,b;
    scanf("%d%d%d",&t,&a,&b);
    if(!t){
    dis[a]=b;
    }
    else{
    memset(ans,0,sizeof(ans));
    cnt = 0;
    int lca=LCA(a,b);
    //printf("LCA(%d,%d)==%d\n",a,b,lca);
    findpar(a,lca);
    findpar(b,lca);
    cnt--;
    //printf("%d\n",cnt);
    if(t>cnt){
     printf("invalid request!\n");
    }
    else{
    sort(ans,ans+cnt,cmp);
    printf("%d\n",ans[t-1]);
    }
    }
    }
}


hdu3078

标签:lca   图论   rmq   

原文地址:http://blog.csdn.net/u013076044/article/details/41923151

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!