zoukankan      html  css  js  c++  java
  • P4408 [NOI2003]逃学的小孩

    题目描述

    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行包含整数Ui、Vi、Ti(1≤Ui, Vi ≤ N,1 ≤ Ti ≤ 1000000000),表示街道i连接居住点Ui和Vi,并且经过街道i需花费Ti分钟。街道信息不会重复给出。

    输出格式

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

    输入输出样例

    输入 #1
    4 3
    1 2 1
    2 3 1
    3 4 1
    输出 #1
    4
    题意:给一棵无根树,选出A,B,C三个点使得AB+BC最大。
    分析:先求出树的直径,再分别从直径的两个端点开始dfs,找到每个点到直径端点的距离。令直径端点为A,B,则答案为dis[A][B]+
    max(min(dis[A][k],dis[B][k])) (k是除了AB之外的点)
       还要注意开longlong
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 200000+5;
     4 typedef long long ll;
     5 struct Node{
     6     int to, dis, next;
     7 }edge[maxn << 1];
     8 ll head[maxn], cnt, p1, p2, t, ans, f[maxn][3];
     9 int n, m;
    10 void Add(int u, int v, int w){
    11     edge[++cnt].to = v;
    12     edge[cnt].next = head[u];
    13     edge[cnt].dis = w;
    14     head[u] = cnt;
    15 }
    16 void Dfs(int rt, int fa, ll sum){
    17     if (ans < sum){
    18         ans = sum;
    19         t = rt;
    20     }
    21     for (int i = head[rt]; i; i = edge[i].next){
    22         int v = edge[i].to, dis = edge[i].dis;
    23         if (v != fa){
    24             Dfs(v, rt, sum + dis);
    25         }
    26     }
    27 }
    28 void Dfs1(int rt, int fa, int k){
    29     for (int i = head[rt]; i; i = edge[i].next){
    30         int v = edge[i].to, dis = edge[i].dis;
    31         if (v == fa) continue;
    32         f[v][k] = f[rt][k] + dis;
    33         Dfs1(v, rt, k);
    34     }
    35 }
    36 int main(){
    37     scanf("%d%d", &n, &m);
    38     for (int i = 1; i <= m; i++){
    39         int u, v, w;
    40         scanf("%d%d%d", &u, &v, &w);
    41         Add(u, v, w);
    42         Add(v, u, w);
    43     }
    44     Dfs(1, 0, 0);
    45     p1 = t; ans = 0;
    46     Dfs(p1, 0, 0);
    47     p2 = t;
    48     Dfs1(p1, 0, 1);
    49     Dfs1(p2, 0, 0);
    50     ll ans1 = 0;
    51     for (int i = 1 ; i <= n; i++){
    52         ans1 = max(ans1, min(f[i][0], f[i][1]));
    53     }
    54     printf("%lld", ans1 + ans);
    55     return 0;
    56 }
    View Code
     
  • 相关阅读:
    win10 下安装pip方法
    visual studio 打开微软MVC3示例MvcMusicStore的详细修改方法
    SQL Server 使用问题解答(持续更新中)
    SQL server数据库备份还原问题备忘(亲测有效)
    visual studio错误中断处理
    Eclipse调试
    nginx +lua +redis 构建自动缓存系统
    批量更新memcached缓存
    SQL Server 2008 表值参数用法
    架构设计方案
  • 原文地址:https://www.cnblogs.com/ghosh/p/12668433.html
Copyright © 2011-2022 走看看