https://vjudge.net/problem/HDU-6115
题意感觉很麻烦
感觉是一个加强版的LCA模板题
tarjan算法确实厉害
根本不用什么倍增,树的重心优化
不开读入挂用cincout
每次超长时间初始化
都可以在一个限时10秒的题2秒跑完
实在是厉害啊
越来越喜欢tarjan了
hiahiahia
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int edge[N],head[N],Next[N],ver[N],v[N],d[N],ans[N],fa[N],tot;
vector<int> query[N],query_id[N],Son[N];
void add(int x,int y,int z){
ver[++tot]=y;
edge[tot]=z;
Next[tot]=head[x];
head[x]=tot;
}
void add_query(int x,int y,int id){
if(x==y) ans[id]=0;
else{
query[x].push_back(y),query_id[x].push_back(id);
query[y].push_back(x),query_id[y].push_back(id);
}
}
int get(int x){
if(x==fa[x]) return x;
else return fa[x]=get(fa[x]);
}
void tarjan(int x){
v[x]=1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(v[y]) continue;
d[y]=d[x]+edge[i];
tarjan(y);
fa[y]=x;
}
for(int i=0;i<query[x].size();++i){
int y=query[x][i],id=query_id[x][i];
if(v[y]==2){
int lca=get(y);
ans[id]=min(ans[id],d[x]+d[y]-d[lca]*2);
}
}
v[x]=2;
}
int main(){
int T;
cin>>T;
while(T--){
int n,m,x,y,z;
cin>>n>>m;
tot=0;
for(int i=1;i<=N-5;++i){
fa[i]=i;edge[i]=0;ans[i]=(1<<30);head[i]=0;Next[i]=0;ver[i]=0;v[i]=0;d[i]=0;
query_id[i].clear();query[i].clear();Son[i].clear();
}
for(int i=1;i<n;++i){
cin>>x>>y>>z;
add(x,y,z),add(y,x,z);
}
for(int i=1;i<=m;++i){
cin>>x;
for(int j=1;j<=x;++j){
cin>>y;
Son[i].push_back(y);
}
}
cin>>m;
for(int i=1;i<=m;++i){
cin>>x>>y;
for(int j=0;j<Son[x].size();++j){
for(int k=0;k<Son[y].size();++k){
add_query(Son[x][j],Son[y][k],i);
}
}
}
tarjan(1);
for(int i=1;i<=m;++i){
cout<<ans[i]<<endl;
}
}
}