HDU3087 LCA+前向型

来源:互联网 发布:淘宝美工是什么意思 编辑:程序博客网 时间:2024/06/07 20:06

我是用LCA做的!!先用前向星初始化处理边    

struct Node
{
int prein,floor;
}T[400000];

int add(int a,int b)//以a到b的边
{
A[tt].to=b;
A[tt].next=head[a];
head[a]=tt++;
return 0;
}//前向星

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;


struct node
{
int to,next;
}A[400000];//双向边尽量开大点
struct Node
{
int prein,floor;
}T[400000];
int head[400000],tt=1,n,dis[400000],mark[400000],leap[400000];
int add(int a,int b)
{
A[tt].to=b;
A[tt].next=head[a];
head[a]=tt++;
return 0;
}
int LCA(int s)
{
int t;
for(int k=head[s];k;k=A[k].next)
{
t=A[k].to;
if(mark[t]!=0) continue;
mark[t]=1;
T[t].prein=s;
T[t].floor=T[s].floor+1;
LCA(t);
}
return 0;
}
int cmp(int a,int b)
{
return a>b;
}
int main()
{
int i,j,a,b,Q;
scanf("%d%d",&n,&Q);
for(i=1;i<=n;i++)
scanf("%d",&dis[i]);
memset(mark,0,sizeof(mark));
memset(head,0,sizeof(head));
for(i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
T[1].prein=1;
T[1].floor=1;
LCA(1);
int k,x;
for(i=1;i<=Q;i++)
{
scanf("%d%d%d",&k,&a,&b);
if(k==0) dis[a]=b;
else
{
j=1;
x=0;
leap[j++]=dis[a];
leap[j++]=dis[b];
x+=2;
while(T[a].floor>T[b].floor)
{
a=T[a].prein;
if(a!=b){x+=1;leap[j++]=dis[a];}
}
while(T[b].floor>T[a].floor)
{
b=T[b].prein;
if(a!=b){x+=1;leap[j++]=dis[b];}
}
while(a!=b)
{
a=T[a].prein;
b=T[b].prein;
if(a!=b)
{
leap[j++]=dis[a];
leap[j++]=dis[b];
x+=2;
}
else {leap[j++]=dis[a];x+=1;}
}
if(x<k) printf("invalid request!\n");
else
{
sort(leap+1,leap+j,cmp);
printf("%d\n",leap[k]);
}
}
}
return 0;
}

0 0
原创粉丝点击