zoukankan      html  css  js  c++  java
  • M 逃学的小孩-------树的直径的应用

    题目

    题目描述

    Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚,他们决定在尽量短的时间内找到Chris。他们告诉Chris的老师:“根据以往的经验,Chris现在必然躲在朋友Shermie或Yashiro家里偷玩《拳皇》游戏。现在,我们就从家出发去找Chris,一但找到,我们立刻给您打电话。”说完砰的一声把电话挂了。

    Chris居住的城市由N个居住点和若干条连接居住点的双向街道组成,经过街道x需花费Tx分钟。可以保证,任两个居住点间有且仅有一条通路。Chris家在点C,Shermie和Yashiro分别住在点A和点B。Chris的老师和Chris的父母都有城市地图,但Chris的父母知道点A、B、C的具体位置而Chris的老师不知。

    为了尽快找到Chris,Chris的父母会遵守以下两条规则:

    1. 如果A距离C比B距离C近,那么Chris的父母先去Shermie家寻找Chris,如果找不到,Chris的父母再去Yashiro家;反之亦然。
    2. Chris的父母总沿着两点间唯一的通路行走。

    显然,Chris的老师知道Chris的父母在寻找Chris的过程中会遵守以上两条规则,但由于他并不知道A,B,C的具体位置,所以现在他希望你告诉他,最坏情况下Chris的父母要耗费多长时间才能找到Chris?

    输入格式

    输入文件第一行是两个整数(N(3 ≤ N ≤ 200000))(M),分别表示居住点总数和街道总数。

    以下(M)行,每行给出一条街道的信息。第(i+1)行包含整数(U_i、V_i、T_i(1≤U_i, V_i ≤ N,1 ≤ Ti ≤ 1000000000)),表示街道(i)连接居住点(U_i)(V_i),并且经过街道(i)需花费(T_i)分钟。街道信息不会重复给出。

    输出格式

    输出文件仅包含整数(T),即最坏情况下Chris的父母需要花费T分钟才能找到Chris。

    样例输入

    4 3
    1 2 1
    2 3 1
    3 4 1
    

    样例输入

    4
    

    题解

    解题思路

    首先两遍(dfs)求出树的直径

    再枚举寻找距离两点最远的点

    代码

    #include <cstdio>
    #include <algorithm>
    #define int long long
    using namespace std;
    const int N = 2e5+5;
    struct side {
    	int t, d, next;
    }a[N*10];
    int tot, head[N];
    void add(int x, int y, int z) {
    	a[++tot].t = y;
    	a[tot].d = z;
    	a[tot].next = head[x];
    	head[x] = tot;
    }
    int n, m, A, B, d[5][N], M = 0, ans = -999;
    void dfs(int x, int fa, int k) {
    	for(int i = head[x]; i; i = a[i].next) {
    		int y  = a[i].t;
    		if (y == fa) continue;
    		d[k][y] = d[k][x] + a[i].d;
    		if ((k == 1 || k == 2) && d[k][M] < d[k][y]) M = y;
    		dfs(y, x, k);
    	}
    }
    signed main() {
    	scanf("%lld%lld", &n, &m);
    	for(int i = 1, x, y, z; i <= m; i++)
    		scanf("%lld%lld%lld", &x, &y, &z),
    		add(x, y, z), add(y, x, z);
    	dfs(1, -1, 1);
    	A = M; M = 0;
    	dfs(A, -1, 2);
    	B = M;
    	dfs(A, -1, 3);
    	dfs(B, -1, 4);
    	for(int i = 1; i <= n; i++)
    		ans = max(ans, min(d[3][i], d[4][i]));
    	ans += d[2][B];
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/Z8875/p/12663170.html
Copyright © 2011-2022 走看看