您的位置:首页 > 其它

【LCA】 HDU 3078 Network

2014-11-08 10:53 337 查看
题意: 一棵树 点有权值

求u-v 的路径上 第 k 大的点权值(包括u和v)

k==0 为更改操作

先LCA 转 RMQ

如果u==v 判断k==1

否则 求 (u,v)的LCA 然后 求u的前驱 和v的前驱 并且把权值存起来

把权值排序 然后输出

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <map>
#define cler(arr, val)    memset(arr, val, sizeof(arr))
typedef long long  LL;
const int MAXN = 100000+6;
const int MAXM = 140000;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
int dp[MAXN*2][25];
struct node
{
int v,next;
}edge[MAXN*2];
int len[MAXN];
int head[MAXN],tol,first[MAXN],time,vis[MAXN*2],dep[MAXN*2],pre[MAXN];
void addedge(int u,int v)
{
edge[tol].v=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void RMQ_init(int n)
{
for(int i = 1; i <= n; i++)
{
dp[i][0] = i;
}
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++)
{
dp[i][j] = dep[dp[i][j-1]] <
dep[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
}
}
}
int RMQ(int l,int r)
{
int k=(int)(log(double(r-l+1))/log((double)2));
return dep[dp[l][k]] <= dep[dp[r-(1<<k)+1][k]]?dp[l][k]:dp[r-(1<<k)+1][k];
}
void dfs(int u,int pr,int deep)
{
vis[++time]=u;
dep[time]=deep;
first[u]=time;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if(v==pr) continue;
pre[v]=u;
dfs(v,u,deep+1);
vis[++time]=u;
dep[time]=deep;
}
}
void init()
{
cler(head,-1);
tol=0;
time=0;
}
vector<int>g;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
int n,m,k;
while(cin>>n>>m)
{
init();
int a,b,c;
for(int i=1;i<=n;i++)
scanf("%d",&len[i]);
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
dfs(1,0,0);
RMQ_init(time);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&k,&a,&b);
if(k==0)
len[a]=b;
else
{
if(a==b)
{
if(k==1) printf("%d\n",len[a]);
else puts("invalid request!");
}
else
{
g.clear();
int u=first[a],v=first[b];
if(u>v) swap(u,v);
int c=RMQ(u,v);
c=vis[c];
g.push_back(len[c]);
while(a!=c)
{
g.push_back(len[a]);
a=pre[a];
}
while(b!=c)
{
g.push_back(len[b]);
b=pre[b];
}
if(g.size()<k)
puts("invalid request!");
else
{
sort(g.begin(),g.end());
printf("%d\n",g[g.size()-k]);
}
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: