1 3 1 1 2 2 3 1 2 3
2
算出 a到c距离,b到c距离 ,算距离用LCA
LCA可以考虑离线的Tarjan算法
Tarjan算法介绍参考这个
http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html
1.注意反向边可以通过 s^1 得到
2.少用#define maxn 1000+5 具体看置顶
代码如下“:
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #define oo 0x13131313 #define maxn 100010 using namespace std; int n,q; struct Edge{int to,ans,next; void GET(int a,int b,int c){to=a,ans=b,next=c;} }; struct Node{int first,deep;}; Edge E[maxn*6],EE[maxn*6]; Node Tree[maxn],Q[maxn]; int _E=0,_EE=0; int a[maxn],b[maxn],c[maxn],visit[maxn],father[maxn]; void init() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); } void CLEAR() { for(int i=1;i<=n;i++) { Tree[i].first=-1; Q[i].first=-1; } memset(visit,0,sizeof(visit)); _E=0;_EE=0; for(int i=1;i<=100001;i++) father[i]=i; } void Link(int u,int v) { E[_E].GET(v,0,Tree[u].first);Tree[u].first=_E++; E[_E].GET(u,0,Tree[v].first);Tree[v].first=_E++; } void Link2(int u,int v) { EE[_EE].GET(v,0,Q[u].first);Q[u].first=_EE++; EE[_EE].GET(u,0,Q[v].first);Q[v].first=_EE++; } int find(int x) { int r=x; while(father[r]!=r) { r=father[r]; } int i=x; while(i!=r) { int j=father[i]; father[i]=r; i=j; } return father[x]; } void input() { int x,y; cin>>n>>q; CLEAR(); for(int i=1;i<=n-1;i++) { scanf("%d%d",&x,&y); Link(x,y); } for(int i=1;i<=q;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); Link2(a[i],c[i]); Link2(b[i],c[i]); } } void Tarjan(int u,int deep) { visit[u]=1; Tree[u].deep=deep; for(int p=Q[u].first;p!=-1;p=EE[p].next) if(visit[EE[p].to]==1) EE[p^1].ans=EE[p].ans=find(EE[p].to); int t=0; for(int p=Tree[u].first;p!=-1;p=E[p].next) { if(visit[E[p].to]==0) { Tarjan(E[p].to,deep+1); father[E[p].to]=u; } } } void solve() { Tarjan(1,1); int AA=0,BB=0,A=0,B=0;; for(int i=1;i<=q;i++) { for(int p=Q[c[i]].first;p!=-1;p=EE[p].next) { if(EE[p].to==a[i]) A=EE[p].ans; if(EE[p].to==b[i]) B=EE[p].ans; } AA=Tree[a[i]].deep+Tree[c[i]].deep-2*Tree[A].deep; BB=Tree[b[i]].deep+Tree[c[i]].deep-2*Tree[B].deep; if(AA<BB) printf("%d\n",a[i]); else printf("%d\n",b[i]); } } int main() { // init(); int T; cin>>T; while(T--) { input(); solve(); } }