求路径中权重最小的点
#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