zoukankan      html  css  js  c++  java
  • BZOJ 1787: [Ahoi2008]Meet 紧急集合

    题目描述

    欢乐岛上有个非常好玩的游戏,叫做“紧急集合”。在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要花费一个游戏币。

    参加游戏的人三人一组,开始的时候,所有人员均任意分散在各个等待点上(每个点同时允许多个人等待),每个人均带有足够多的游戏币(用于支付使用道路的花费)、地图(标明等待点之间道路连接的情况)以及对话机(用于和同组的成员联系)。当集合号吹响后,每组成员之间迅速联系,了解到自己组所有成员所在的等待点后,迅速在N个等待点中确定一个集结点,组内所有成员将在该集合点集合,集合所用花费最少的组将是游戏的赢家。

    小可可和他的朋友邀请你一起参加这个游戏,由你来选择集合点,聪明的你能够完成这个任务,帮助小可可赢得游戏吗?

     题解:手画一下,选择三个点两两组成 LCA 中深度最大的即可. 

    #include<bits/stdc++.h>
    #define maxn 600000 
    using namespace std; 
    void setIO(string s)
    {
    	string in=s+".in"; 
    	freopen(in.c_str(),"r",stdin); 
    }
    int edges,n,Q; 
    int hd[maxn],to[maxn<<1],nex[maxn<<1],dep[maxn],siz[maxn],hson[maxn],fa[maxn],top[maxn];  
    void add(int u,int v)
    {
    	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
    }
    void dfs1(int u,int ff)
    {
    	fa[u]=ff,dep[u]=dep[ff]+1,siz[u]=1; 
    	for(int i=hd[u];i;i=nex[i])
    	{
    		int v=to[i];
    		if(v==ff) continue; 
    		dfs1(v,u); 
    		siz[u]+=siz[v]; 
    		if(siz[v]>siz[hson[u]]) hson[u]=v; 
    	}
    }
    void dfs2(int u,int tp)
    {
    	top[u]=tp; 
    	if(hson[u]) dfs2(hson[u],tp); 
    	for(int i=hd[u];i;i=nex[i])
    	{
    		int v=to[i]; 
    		if(v==fa[u]||v==hson[u]) continue; 
    		dfs2(v,v); 
    	}
    }
    int LCA(int x,int y)
    {
    	while(top[x]^top[y]) dep[top[x]] > dep[top[y]] ? x = fa[top[x]] : y = fa[top[y]]; 
    	return dep[x] < dep[y] ? x : y; 
    }
    int Getdis(int x,int y)
    {
    	return dep[x] + dep[y] - (dep[LCA(x,y)]<<1); 
    }
    int main()
    {
    	// setIO("input"); 
    	scanf("%d%d",&n,&Q);
    	for(int i=1,u,v;i<n;++i)  
    	{
    		scanf("%d%d",&u,&v); 
    		add(u,v), add(v,u); 
    	}
    	dfs1(1,0); 
    	dfs2(1,1);    
    	int u,v,t; 
    	while(Q--)
    	{
    		scanf("%d%d%d",&u,&v,&t); 
    		int d1=LCA(u,v),d2=LCA(u,t),cur,d3=LCA(v,t); 
    		cur=dep[d1]<dep[d2]?d2:d1;
    		cur=dep[cur]<dep[d3]?d3:cur; 
    		printf("%d %d
    ",cur,Getdis(u,cur)+Getdis(v,cur)+Getdis(t,cur)); 
    	}
    	return 0; 
    }
    

      

  • 相关阅读:
    java基础16 捕获、抛出以、自定义异常和 finally 块(以及关键字:throw 、throws)
    java基础15 内部类(成员内部类、局部内部类)和匿名内部类
    java基础14 多态(及关键字:instanceof)
    java基础13 接口(及关键字:interface、implements)
    Java 线程控制
    Java 多线程创建和线程状态
    Java New IO
    Java IO流
    Java 集合和泛型
    Java 动态代理
  • 原文地址:https://www.cnblogs.com/guangheli/p/11013912.html
Copyright © 2011-2022 走看看