//2022/1/4
//2022/1/5
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <cstring>//need "memset"
#include <algorithm>
#define enter() putchar(10)
#define debug(c,que) cerr<<#c<<" = "<<c<<que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i=(st);i<=(ed);i++)cout<<arr[i]<<w;
#define speed_up() cin.tie(0),cout.tie(0)
#define endl "\n"
#define Input_Int(n,a) for(register int i=1;i<=n;i++)scanf("%d",a+i);
#define Input_Long(n,a) for(register long long i=1;i<=n;i++)scanf("%lld",a+i);
#define mst(a,k) memset(a,k,sizeof(a))
namespace Newstd
{
inline int read()
{
int x=0,k=1;
char ch=getchar();
while(ch<'0' || ch>'9')
{
if(ch=='-')
{
k=-1;
}
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*k;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
}
using namespace Newstd;
using namespace std;
const int INF=0x3f3f3f3f;
const int ma=1e5+5;
struct Gragh
{
int v;
int nxt;
};
Gragh gra[ma<<1];
int head[ma],dep[ma],lg[ma],res1[ma],res2[ma];
int fa[ma][31],w[ma][21];
int dis[ma][31][21];
//dis[i][j][k]:i 向上跳 2^{j}-1 步后第 k 小的值
int n,m,q;
int idx;
inline void add(int u,int v)
{
gra[++idx].v=v;
gra[idx].nxt=head[u];
head[u]=idx;
}
inline void init()
{
for(register int i=1;i<=n;i++)
{
lg[i]=lg[i>>1]+1;
}
}
inline void dfs(int now,int fath,int depth)
{
fa[now][0]=fath;
dep[now]=depth;
for(register int i=head[now];i;i=gra[i].nxt)
{
int v=gra[i].v;
if(v!=fath)
{
dfs(v,now,depth+1);
}
}
}
inline int LCA(int x,int y)
{
if(dep[x]<dep[y])
{
swap(x,y);
}
while(dep[x]>dep[y])
{
x=fa[x][lg[dep[x]-dep[y]]-1];
}
if(x==y)
{
return x;
}
for(register int i=30;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
inline void updata1(int x,int y)
{
mst(res1,0x3f);
for(register int i=30;i>=0;i--)
{
if(dep[x]>=dep[y]+(1<<i))
{
for(register int j=1;j<=10;j++)
{
res1[j+10]=dis[x][i][j];
}
sort(res1+1,res1+20+1);
x=fa[x][i];
}
}
}
inline void updata2(int x,int y)
{
mst(res2,0x3f);
for(register int i=30;i>=0;i--)
{
if(dep[x]>=dep[y]+(1<<i))
{
for(register int j=1;j<=10;j++)
{
res2[j+10]=dis[x][i][j];
}
sort(res2+1,res2+20+1);
x=fa[x][i];
}
}
}
inline void query(int x,int y,int a)
{
int ans=0;
int lca=LCA(x,y);
if(lca==x)
{
updata1(y,x);
for(register int i=1;i<=10;i++)
{
res1[i+10]=w[x][i];
}
sort(res1+1,res1+20+1);
for(register int i=1;i<=a;i++)
{
if(res1[i]!=INF)
{
ans++;
}
}
printf("%d ",ans);
for(register int i=1;i<=a;i++)
{
if(res1[i]!=INF)
{
printf("%d ",res1[i]);
}
}
enter();
}
else if(lca==y)
{
swap(x,y);
updata1(y,x);
for(register int i=1;i<=10;i++)
{
res1[i+10]=w[x][i];
}
sort(res1+1,res1+20+1);
for(register int i=1;i<=a;i++)
{
if(res1[i]!=INF)
{
ans++;
}
}
printf("%d ",ans);
for(register int i=1;i<=a;i++)
{
if(res1[i]!=INF)
{
printf("%d ",res1[i]);
}
}
enter();
}
else
{
updata1(x,lca);
updata2(y,lca);
for(register int i=1;i<=10;i++)
{
res1[i+10]=res2[i];
}
sort(res1+1,res1+20+1);
for(register int i=1;i<=10;i++)
{
res1[i+10]=w[lca][i];
}
sort(res1+1,res1+20+1);
for(register int i=1;i<=a;i++)
{
if(res1[i]!=INF)
{
ans++;
}
}
printf("%d ",ans);
for(register int i=1;i<=a;i++)
{
if(res1[i]!=INF)
{
printf("%d ",res1[i]);
}
}
enter();
}
}
int main(void)
{
mst(w,0x3f);mst(dis,0x3f);
n=read(),m=read(),q=read();
for(register int i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
for(register int i=1;i<=m;i++)
{
int x=read();
w[x][11]=i;
sort(w[x]+1,w[x]+11+1);
}
init();
dfs(1,0,1);
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=10;j++)
{
dis[i][0][j]=w[i][j];
}
}
for(register int j=1;j<=30;j++)
{
for(register int i=1;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-1]][j-1];
for(register int k=1;k<=10;k++)
{
dis[i][j][k]=dis[fa[i][j-1]][j-1][k];
dis[i][j][k+10]=dis[i][j-1][k];
}
sort(dis[i][j]+1,dis[i][j]+20+1);
}
}
while(q--)
{
int u=read(),v=read(),a=read();
query(u,v,a);
}
return 0;
}
对着改的代码(快改得一模一样了):
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
namespace Quick_Function {
template <typename Temp> void Read(Temp &x) {
x = 0;
char ch = getchar();
bool op = 0;
while (ch < '0' || ch > '9') {
if (ch == '-') op = 1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
if (op) x = -x;
}
template <typename T, typename... Args> void Read(T &t, Args &... args) {
Read(t);
Read(args...);
}
template <typename Temp> Temp Max(Temp x, Temp y) {
return x > y ? x : y;
}
template <typename Temp> Temp Min(Temp x, Temp y) {
return x < y ? x : y;
}
template <typename Temp> Temp Abs(Temp x) {
return x < 0 ? (-x) : x;
}
template <typename Temp> void Swap(Temp &x, Temp &y) {
x ^= y ^= x ^= y;
}
}
using namespace Quick_Function;
#define INF 0x3f3f3f3f
const int MAXN = 1e5 + 5;
struct Edge {
int Next, To;
};
Edge edge[MAXN << 1];
int head[MAXN], edgetot = 1;
void Addedge(int u, int v) {
edge[++edgetot].Next = head[u], edge[edgetot].To = v, head[u] = edgetot;
edge[++edgetot].Next = head[v], edge[edgetot].To = u, head[v] = edgetot;
}
int w[MAXN][21];
int n, m, q, a;
int dep[MAXN], fa[MAXN][31], dis[MAXN][31][21];
int res1[21], res2[21];
int Get_Lca(int x, int y) {
if (dep[x] < dep[y]) Swap(x, y);
for (int i = 30; i >= 0; i--)
if (dep[x] - (1 << i) >= dep[y]) x = fa[x][i];
if (x == y) return x;
for (int i = 30; i >= 0; i--)
if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
void dfs(int u, int step) {
dep[u] = step;
for (int i = head[u]; i; i = edge[i].Next) {
int v = edge[i].To;
if (v != fa[u][0]) {
fa[v][0] = u;
dfs(v, step + 1);
}
}
}
void Upclimb1(int x, int y) {
memset(res1, 0x3f, sizeof(res1));
for (int i = 30; i >= 0; i--)
if (dep[x] - (1 << i) >= dep[y]) {
for (int k = 1; k <= 10; k++) res1[k + 10] = dis[x][i][k];
sort(res1 + 1, res1 + 1 + 20);
x = fa[x][i];
}
}
void Upclimb2(int x, int y) {
memset(res2, 0x3f, sizeof(res2));
for (int i = 30; i >= 0; i--)
if (dep[x] - (1 << i) >= dep[y]) {
for (int k = 1; k <= 10; k++) res2[k + 10] = dis[x][i][k];
sort(res2 + 1, res2 + 1 + 20);
x = fa[x][i];
}
}
void Query(int x, int y) {
int ans = 0;
int lca = Get_Lca(x, y);
if (lca == x) {
Upclimb1(y, x);
for (int i = 1; i <= 10; i++) res1[i + 10] = w[x][i];
sort(res1 + 1, res1 + 1 + 20);
for (int i = 1; i <= a; i++)
if (res1[i] != INF) ans++;
printf("%d ", ans);
for (int i = 1; i <= a; i++)
if (res1[i] != INF) printf("%d ", res1[i]);
return;
}
if (lca == y) {
Swap(x, y);
Upclimb1(y, x);
for (int i = 1; i <= 10; i++) res1[i + 10] = w[x][i];
sort(res1 + 1, res1 + 1 + 20);
for (int i = 1; i <= a; i++)
if (res1[i] != INF) ans++;
printf("%d ", ans);
for (int i = 1; i <= a; i++)
if (res1[i] != INF) printf("%d ", res1[i]);
return;
}
Upclimb1(x, lca);
Upclimb2(y, lca);
for (int i = 1; i <= 10; i++) res1[i + 10] = res2[i];
sort(res1 + 1, res1 + 1 + 20);
for (int i = 1; i <= 10; i++) res1[i + 10] = w[lca][i];
sort(res1 + 1, res1 + 1 + 20);
for (int i = 1; i <= a; i++)
if (res1[i] != INF) ans++;
printf("%d ", ans);
for (int i = 1; i <= a; i++)
if (res1[i] != INF) printf("%d ", res1[i]);
}
int main() {
memset(w, 0x3f, sizeof(w));
memset(dis, 0x3f, sizeof(dis));
Read(n, m, q);
for (int i = 1, u, v; i < n; i++)
Read(u, v), Addedge(u, v);
for (int i = 1, a; i <= m; i++) {
Read(a);
w[a][11] = i;
sort(w[a] + 1, w[a] + 1 + 11);
}
dfs(1, 0);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= 10; j++) dis[i][0][j] = w[i][j];
for (int j = 1; j <= 30; j++)
for (int i = 1; i <= n; i++) {
fa[i][j] = fa[fa[i][j - 1]][j - 1];
for (int k = 1; k <= 10; k++)
dis[i][j][k] = dis[fa[i][j - 1]][j - 1][k];
for (int k = 1; k <= 10; k++)
dis[i][j][k + 10] = dis[i][j - 1][k];
sort(dis[i][j] + 1, dis[i][j] + 1 + 20);
}
int u, v;
while (q--) {
Read(u, v, a);
Query(u, v);
printf("\n");
}
return 0;
}