zoukankan      html  css  js  c++  java
  • LUOGU 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

    解析:

    用SPFA做树的直径,与普通的SPFA大致相同,只要在最后加上一重for循环记录距离最大的点即可;

    求树的直径是只要做两遍SPFA就可以了;

    #include<bits/stdc++.h>
    using namespace std;
    #define rint register int 
    #define ll long long
    
    inline int read(){
        int x=0,f=0;char ch=getchar();
        while(!isdigit(ch))    f=(ch==45),ch=getchar();
        while( isdigit(ch))    x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        return f?(~x+1):x;
    }
    
    #define man 200050
    
    struct edge{int next,to,dis;}e[man<<1];
    int head[man<<1],num=0;
    
    inline void add(int from,int to,int dis){
        e[++num]=(edge){head[from],to,dis};
        head[from]=num;
    }
    int n,m; int vis[man]; ll dis0[man],disa[man],disb[man]; inline int spfa(int s,ll dis[]){ for(rint i=1;i<=n;i++) dis[i]=2e11+9,vis[i]=0; queue<int>q; q.push(s);dis[s]=0;vis[s]=1; do{ int u=q.front();q.pop();vis[u]=0; for(rint i=head[u];i;i=e[i].next){ int to=e[i].to; if(dis[to]>dis[u]+e[i].dis){ dis[to]=dis[u]+e[i].dis; if(!vis[to]){ vis[to]=1; q.push(to); } } } }while(!q.empty()); ll maxn=0;int pos=s; for(rint i=1;i<=n;i++){ if(maxn<dis[i]) maxn=dis[i],pos=i; } return pos; } int main(){ n=read();m=read(); for(rint i=1,x,y,z;i<=m;i++){ x=read();y=read();z=read(); add(x,y,z);add(y,x,z); } rint a=spfa(1,dis0); rint b=spfa(a,disa); spfa(b,disb); ll ans=disa[b],maxn=0; for(rint i=1;i<=n;i++) maxn=max(maxn,min(disa[i],disb[i])); printf("%lld ",ans+maxn); return 0; }
  • 相关阅读:
    Linux常用命令-centos
    USACO 2006 Open, Problem. The Country Fair 动态规划
    USACO 2007 March Contest, Silver Problem 1. Cow Traffic
    USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法
    USACO 2015 February Contest, Silver Problem 3. Superbull Prim最小生成树算法
    LG-P2804 神秘数字/LG-P1196 火柴排队 归并排序, 逆序对
    数据结构 并查集
    浴谷国庆集训 对拍
    1999 NOIP 回文数
    2010 NOIP 普及组 第3题 导弹拦截
  • 原文地址:https://www.cnblogs.com/Slager-Z/p/9873332.html
Copyright © 2011-2022 走看看