zoukankan      html  css  js  c++  java
  • 洛谷 P3174 【[HAOI2009]毛毛虫】

    一看这道题立马想到了树的直径

    还没有两遍(dfs)求树的直径的做法,赶快来水一发


    已经会树的直径的大佬可以跳过这一段(qwq)

    树的直径:树上最长的一条链

    具体求法有两种,一种是树形(DP),这里就不细讲了,我着重讲下两遍(dfs)求树的直径的做法,可以说很经典了。

    做法: 先从任意一点出发,找到离出发点的最远点,然后再从找到的那个点出发,找一次最远点,这两点就是树的直径的两个端点。


    以下是证明(也不是必须会证明啦,不想看的(dalao)可以跳过)

    (dis)的意思是两点直接的长度,图片中两点之间的长度是不确定的,比如(1)(2)之间可能有多个节点,只是简洁点画


    接下来回到这道题,跟树的直径是不是就有点联系了,树的直径的(dfs)的时候每延申(1)个点,我们只需要加上(1)个长度,而这道题应该这样加:

    假设我们(dfs)(x)开始,那么我们一开始初始的总和为(dis[x])(dis)为这个点连到的所有点),设(nx)(x)的儿子,那么往(nx)展的时候,应该加上(dis[nx]-2),因为当搜到(nx)的时候,首先他自己这个点,已经被他的父亲(x)加过了,而且(nx)还连了一个(x)(x)被父亲自己加过了,所以不需要再加了,所以减(2)

    思路讲完了,下面是代码时间~

    #include <bits/stdc++.h>
    using namespace std;
    int n , m , ans1 , ans2 , maxx , tot , f = 0;	//ans1为第一次的最远点,ans2为第二次的最远点 
    int dis[300010];
    vector<int> e[300010]; 
    stack<int> s;
    void dfs1(int x , int sum , int fa){
    	if(maxx < sum){
    		maxx = sum;
    		ans1 = x;
    	}
    	for(int i = 0; i < e[x].size(); i++){
    		int nx = e[x][i];
    		if(nx == fa) continue;
    		dfs1(nx , sum + dis[nx] - 2 , x);
    	}
    } 
    void dfs2(int x , int sum , int fa){
    	if(tot < sum){
    		ans2 = x;
    		tot = sum;
    	}
    	for(int i = 0; i < e[x].size(); i++){
    		int nx = e[x][i];
    		if(nx == fa) continue;
    		dfs2(nx , sum + dis[nx] - 2 , x);
    	}
    }
    int main(){
    	cin >> n >> m;
    	for(int i = 1; i <= n; i++) dis[i]++;	//自己也算连到了 
    	for(int i = 1; i <= m; i++){
    		int x , y;
    		cin >> x >> y;
    		e[x].push_back(y);
    		e[y].push_back(x);
    		dis[x]++;
    		dis[y]++;
    	}
    	dfs1(1 , dis[1] , 0);
    	dfs2(ans1 , dis[ans1] , 0);
    	cout << tot;
    	return 0;
    }
    
  • 相关阅读:
    现代程序设计——homework-01
    数据结构 学习笔记03——栈与队列
    MCI 函数与命令
    mciSendString用法
    VC6.0 error LNK2001: unresolved external symbol _main解决办法
    数据结构 学习笔记02——线性表
    数据结构 学习笔记01
    《windows程序设计》学习_4:文本输出,加滚动条
    浅析指针(pointer)与引用(reference)
    指针数组 | 数组指针
  • 原文地址:https://www.cnblogs.com/bzzs/p/13674669.html
Copyright © 2011-2022 走看看