zoukankan      html  css  js  c++  java
  • CF1294F Three Paths on a Tree

    CF1294F Three Paths on a Tree

    洛谷传送门

    题意翻译

    给定一棵含 n (3leq nleq2cdot 10^5)n (3≤n≤2⋅105) 个结点的无权树,试找出三个结点 uu、vv、ww,operatorname{s.t.}s.t.

    operatorname{card}({u,v ext{ 间的路径}}cup{v,w ext{ 间的路径}}cup{w,u ext{ 间的路径}})card({u,v 间的路径}∪{v,w 间的路径}∪{w,u 间的路径})

    最大。

    你需要输出两行:

    第一行为 maxoperatorname{card}({u,v ext{ 间的路径}}cup{v,w ext{ 间的路径}}cup{w,u ext{ 间的路径}})maxcard({u,v 间的路径}∪{v,w 间的路径}∪{w,u 间的路径})

    第二行三个整数,即 uu、vv、ww,如有多种答案,输出一种即可。


    题解:

    贪心+树。

    首先简单想一想能发现:答案应该是树的直径加上所有不在直径上的节点中,距离直径最长的距离。

    那么只需要模拟这个过程就可以:

    先两次DFS求出树的直径(记录路径长和两个端点),然后把直径上所有节点打上标记,然后枚举所有非直径上的节点,更新最大距离,就可以过了。

    复杂度是(O(n))级别。

    代码:

    #include<cstdio>
    using namespace std;
    const int maxn=2e5+5;
    int n;
    int tot,head[maxn],nxt[maxn<<1],to[maxn<<1];
    int maxx,pos[4],ans;
    int deep[maxn],fa[maxn];
    bool v[maxn];
    void add(int x,int y)
    {
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    void dfs(int x,int f,int p)
    {
    	if(p==2)
    		fa[x]=f;
    	deep[x]=deep[f]+1;
    	if(deep[x]>maxx)
    	{
    		maxx=deep[x];
    		pos[p]=x;
    	}
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		if(y==f)
    			continue;
    		dfs(y,x,p);
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<n;i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	deep[0]=-1;
    	dfs(1,0,1);
    	maxx=0;
    	dfs(pos[1],0,2);
    	int x=pos[2];
    	while(x)
    	{
    		v[x]=1;
    		x=fa[x];
    	}
    	ans+=maxx;
    	maxx=0;
    	int tmp=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(v[i])
    			continue;
    		else
    		{
    			x=i;
    			tmp=0;
    			while(!v[x])
    			{
    				x=fa[x];
    				tmp++;
    			}
    			if(maxx<tmp)
    			{
    				maxx=tmp;
    				pos[3]=i;
    			}
    		}
    	}
    	if(!maxx)
    		for(int i=1;i<=n;i++)
    			if(v[i]&&i!=pos[1]&&i!=pos[2])
    			{
    				pos[3]=i;
    				break;
    			}
    	ans+=maxx;
    	printf("%d
    %d %d %d
    ",ans,pos[1],pos[2],pos[3]);
    	return 0;
    }
    
  • 相关阅读:
    EL表达式
    使用Cookie保存用户信息
    GUI学习之二——PyQt控件初识
    GUI学习之一——PyQt5初识
    HTML学习总结
    centos7 mysql的安装与配置
    Python之RabbitMQ的使用
    python之模块的导入
    Python之ftp服务器
    GUI学习之〇——PyQt5安装
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14085988.html
Copyright © 2011-2022 走看看