转换成抽象模型,就是要求一棵树(N个点,有N-1条边表示这个图是棵树)中某一点满足给定三点a,b,c到某一点的距离和最小。那么我们想到最近公共祖先的定义,推出只有集合点在LCA(a,b)、LCA(a,c)、LCA(b,c)中,才能保证距离和最近。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Edge{int to, next;}edge[N<<];
int head[N], tot, fa[N][], deg[N];
queue<int>que; void add_edge(int u, int v){edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++;}
void init(){tot=; mem(head,-);}
void BFS(int root){
deg[root]=; fa[root][]=root; que.push(root);
while (!que.empty()) {
int tmp=que.front(); que.pop();
FO(i,,) fa[tmp][i]=fa[fa[tmp][i-]][i-];
for (int i=head[tmp]; i!=-; i=edge[i].next) {
int v=edge[i].to;
if (v==fa[tmp][]) continue;
deg[v]=deg[tmp]+; fa[v][]=tmp; que.push(v);
}
}
}
int LCA(int u, int v){
if (deg[u]>deg[v]) swap(u,v);
int hu=deg[u], hv=deg[v], tu=u, tv=v;
for (int det=hv-hu, i=; det; det>>=, i++) if (det&) tv=fa[tv][i];
if (tu==tv) return tu;
for (int i=; i>=; --i) {
if (fa[tu][i]==fa[tv][i]) continue;
tu=fa[tu][i]; tv=fa[tv][i];
}
return fa[tu][];
}
int main ()
{
int n, m, u, v, w, x, y, tmp, p;
init();
n=Scan(); m=Scan();
FO(i,,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
BFS();
while (m--) {
int ans=INF;
scanf("%d%d%d",&u,&v,&w);
x=LCA(u,v); tmp=deg[u]+deg[v]-*deg[x];
y=LCA(x,w); tmp+=(deg[x]+deg[w]-*deg[y]);
if (ans>tmp) p=x, ans=tmp;
x=LCA(u,w); tmp=deg[u]+deg[w]-*deg[x];
y=LCA(x,v); tmp+=(deg[x]+deg[v]-*deg[y]);
if (ans>tmp) p=x, ans=tmp;
x=LCA(v,w); tmp=deg[v]+deg[w]-*deg[x];
y=LCA(x,u); tmp+=(deg[x]+deg[u]-*deg[y]);
if (ans>tmp) p=x, ans=tmp;
printf("%d %d\n",p,ans);
}
return ;
}

复杂度O(n+m*logn).

最新文章

  1. jQuery源码分析系列
  2. Python的由来
  3. SQL Server 数据库基础编程
  4. desin pattern
  5. ASP.NET实现IE下禁用浏览器后退按钮办法
  6. java之反射
  7. 为什么我的gridview.DataKeys.count总是为零?并提示索引超出范围
  8. maven的tomcat插件启动报错
  9. MSVC 12: compiler error in boost/type_traits/common_type.hpp
  10. 教你用ActiveReports分析京东双十一数据的价值
  11. Linux wget 命令下载文件
  12. 获取SQL Server中连接的客户端IP地址[转]
  13. vc 6.0 远程调试
  14. DIRECT Project
  15. Android获取网络图片应用示例
  16. mysql随机查询符合条件的几条记录
  17. bluebird -1 New Promise方法
  18. VK Cup 2016 - Round 1 (Div. 2 Edition) E. Bear and Contribution 单调队列
  19. nfs挂载权限问题
  20. Java中String对象的创建

热门文章

  1. PS灰度蒙版建立
  2. Java设计模式(2)——创建型模式之工厂方法模式(Factory Method)
  3. NoSQL入门第四天——事务与主从复制
  4. DevExpress 学习链接
  5. 杭州优步uber司机第三组奖励政策
  6. 【调试】Linux下超强内存检测工具Valgrind
  7. Flume直接对接SaprkStreaming的两种方式
  8. linux常用的命令之一chmod
  9. Qt 报错onecoreuap\inetcore\urlmon\zones\zoneidentifier.cxx(359)\urlmon.dll!00007FF9D9FA5B50:
  10. JAVA Map 之元素定位,冲突碰撞