zoukankan      html  css  js  c++  java
  • P4281 [AHOI2008]紧急集合 / 聚会

    题意描述:

    Link

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

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

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


    最近公共祖先 水题

    一句话题意,让你找到一个点使得给出的三个点到这个点的距离尽可能的小。

    手玩样例可以发现,他只会是任意两点之间的最近公共祖先,就直接枚举一下就行。

    具体证明的话,就是说这样会使重复的路径尽可能的少。 (bushi).

    好像还有一种 (O(1)) 的做法,主要是我没看懂。

    但树剖常数小, (5e5) 的数据跑的没有问题。

    Code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 5e5+10;
    int n,m,u,v,x,y,z,ans,id,tot;
    int dep[N],siz[N],son[N],top[N],head[N],fa[N];
    struct node
    {
    	int to,net;
    }e[N<<1];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    	return s * w;
    }
    void add(int x,int y)
    {
    	e[++tot].to = y;
    	e[tot].net = head[x];
    	head[x] = tot;
    }
    void get_tree(int x)
    {
    	dep[x] = dep[fa[x]] + 1; siz[x] = 1;
    	for(int i = head[x]; i; i = e[i].net)
    	{
    		int to = e[i].to;
    		if(to == fa[x]) continue;
    		fa[to] = x;
    		get_tree(to);
    		siz[x] += siz[to];
    		if(siz[to] > siz[son[x]]) son[x] = to;
    	}
    }
    void dfs(int x,int topp)
    {
    	top[x] = topp;
    	if(son[x]) dfs(son[x],topp);
    	for(int i = head[x]; i; i = e[i].net)
    	{
    		int to = e[i].to;
    		if(to == fa[x] || to == son[x]) continue;
    		dfs(to,to);
    	}
    }
    int lca(int x,int y)
    {
    	while(top[x] != top[y])
    	{
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		x = fa[top[x]];
    	}
    	return dep[x] <= dep[y] ? x : y;
    }
    int dis(int x,int y)
    {
    	return dep[x] + dep[y] - 2 * dep[lca(x,y)];
    }
    int main()
    {
    	n = read(); m = read();
    	for(int i = 1; i <= n-1; i++)
    	{
    		u = read(); v = read();
    		add(u,v); add(v,u);
    	}
    	get_tree(1); dfs(1,1);
    	for(int i = 1; i <= m; i++)
    	{
    		x = read(); y = read(); z = read(); ans = 2147483647;
    		int Lca = lca(x,y);
    		int a = dis(x,Lca), b = dis(y,Lca), c = dis(z,Lca);
    		if(ans > a+b+c)
    		{
    			ans = a+b+c;
    			id = Lca;
    		}
    		Lca = lca(x,z);
    		a = dis(x,Lca), b = dis(y,Lca), c = dis(z,Lca);
    		if(ans > a+b+c)
    		{
    			ans = a+b+c;
    			id = Lca;
    		}
    		Lca = lca(y,z);
    		a = dis(x,Lca), b = dis(y,Lca), c = dis(z,Lca);
    		if(ans > a+b+c)
    		{
    			ans = a+b+c;
    			id = Lca;
    		}
    		printf("%d %d
    ",id,ans);
    	}	
    	return 0;
    }
    
  • 相关阅读:
    python安装依赖包方法
    python 连接mysql数据库
    python学习5 爬虫老是被封如何解决
    python4
    python mysql增删改查
    jieba.analyse jieba.textrank 简单用法
    记录一些小问题
    《面向模式的软件体系架构》读书笔记(三)
    《面向模式的软件体系架构》读书笔记(二)
    安全性战术
  • 原文地址:https://www.cnblogs.com/genshy/p/13850117.html
Copyright © 2011-2022 走看看