hdu3078

来源:互联网 发布:参考文献来源于网络 编辑:程序博客网 时间:2024/05/22 17:08

求路径中权重最小的点

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cmath>using namespace std;typedef long long ll;#define N 80010int 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]);    }    }    }}


0 0
原创粉丝点击