标签:color struct network printf can ext using col add
题意:
一棵无向树,输入点数和操作数,下面一行n个值代表每个点的权。下面n-1行是树边 操作分为 0 x w ,表示把点x的权改为w; k a b , 求出,从a到b的路径中,第k大的点权
题解:
对于每组询问,先求出两点的LCA,再从两点分别向LCA遍历,保存路径上所有的点权,排序输出第K大即可~
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; const int maxn=1e5+10; int N,M,Q; int t[maxn]; int cnt=0; int head[maxn]; int tol; struct node { int u; int v; int w; int next; }edge[maxn*2]; void addedge (int u,int v) { edge[tol].u=u; edge[tol].v=v; edge[tol].next=head[u]; head[u]=tol++; } int weight[maxn]; int d[maxn]; int h[maxn]; int father[20][maxn]; void dfs (int x) { for (int i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].v; if (v==father[0][x]) continue; father[0][v]=x; h[v]=h[x]+1; dfs(v); } } int lca (int x,int y) { if (h[x]<h[y]) swap(x,y); for (int i=17;i>=0;i--) if (h[x]-h[y]>>i) x=father[i][x]; if (x==y) return x; for (int i=17;i>=0;i--) { if (father[i][x]!=father[i][y]) { x=father[i][x]; y=father[i][y]; } } return father[0][x]; } int main () { scanf("%d%d",&N,&Q); memset(head,-1,sizeof(head)); for (int i=1;i<=N;i++) scanf("%d",&weight[i]); for (int i=0;i<N-1;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs(1); for (int i=1;i<=17;i++) for (int j=1;j<=N;j++) father[i][j]=father[i-1][father[i-1][j]]; for (int i=0;i<Q;i++) { int k,x,y; scanf("%d%d%d",&k,&x,&y); if (k==0) weight[x]=y; else { int r=lca(x,y); cnt=0; while (x!=r) { t[cnt++]=weight[x]; x=father[0][x]; } while (y!=r) { t[cnt++]=weight[y]; y=father[0][y]; } t[cnt++]=weight[r]; sort(t,t+cnt); if (cnt<k) { printf("invalid request!\n"); continue; } printf("%d\n",t[cnt-k]); } } }
标签:color struct network printf can ext using col add
原文地址:https://www.cnblogs.com/zhanglichen/p/12527160.html