求路径中权重最小的点
#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]);
}
}
}
}原文地址:http://blog.csdn.net/u013076044/article/details/41923151