我也不知道这是什么类型的题目。。。
数据挺水
把卖商品p的第i个城市设为pi
我们求的是(a, pi)的路径的所有点到b的最近距离
先以b为根节点建树,显然(a, pi)路径上离b最近的点是a与pi的最近公共祖先S
也就是说,a, pi在以S为根的子树内
寻找S的方法是:将a到b的路径上所有的点都mark
pi往上走的时候遇到的第一个被标记的节点就是S
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
#define INF 1e9
#define maxn 10010
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define mset(x) memset(x,0,sizeof(x))
int n, k, a, b, p, q;
int f[maxn];
vector<int> G[maxn];
vector<int> product[maxn];
int dist[maxn];
int pa[maxn];
bool vis[maxn];
void init(){
rep(i,1,n) G[i].clear();
rep(i,1,k) product[i].clear();
mset(dist);
memset(pa, -1, sizeof(pa));
}
void getDist(int u, int fa){
for(int i=0; i<G[u].size(); i++)
{
int v = G[u][i];
if(v == fa) continue;
dist[v] = dist[u] + 1;
pa[v] = u;
getDist(v, u);
}
}
int solve(){
if(product[p].size()==0)
return -1;
memset(vis, 0, sizeof(vis));
int fa=a;
while(fa != b){
vis[fa] = 1;
fa = pa[fa];
}
vis[b]=1;
int maxdist = 0, ans = INF;
for(int i=0; i<product[p].size(); i++)
{
int city = product[p][i];
fa = city;
while(!vis[fa] && fa!=b){
fa = pa[fa];
}
//fa 为 a 与 city 共同的根节点
if(dist[fa] > maxdist)
{
ans = city;
maxdist = dist[fa];
}
if(dist[fa] == maxdist && city < ans){
ans = city;
}
}
return ans;
}
int main(){
while(cin>>n>>k)
{
cin>>b;
init();
int x, y;
rep(i,1,n-1){
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
rep(i,1,n){
scanf("%d", &f[i]);
product[f[i]].push_back(i);
}
getDist(b, -1);
cin>>q;
rep(i,1,q){
scanf("%d %d", &a, &p);
int res = solve();
printf("%d\n", res);
}
}
return 0;
}