• 喵哈哈村的魔法考试 Round #19 (Div.2) C 树的直径 spfa


    喵哈哈村有一个魔法源泉,里面有无穷无尽的力量。

    但是前提是你能答出这样一个问题:

    小T打算在城市C开设一家外送快餐店。送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方。

    快餐店的顾客分布在城市C的N个建筑中,这N个建筑通过恰好N-1条双向道路连接起来,不存在任何两条道路连接了相同的两个建筑。任意两个建筑之间至少存在一条由双向道路连接而成的路径。小T的快餐店可以开设在任一建筑中,也可以开设在任意一条道路的某个位置上(该位置与道路两端的建筑的距离不一定是整数)。

    现给定城市C的地图(道路分布及其长度),请找出最佳的快餐店选址,输出其与最远的顾客之间的距离。

    第一行包含一个整数N,表示城市C中的建筑和道路数目
    接下来N-1行,每行3个整数,Ai,Bi,Li(1≤i≤N;Li>0),表示一条道路连接了建筑Ai与Bi,其长度为Li

    满足:,n<=200000,Li<=10000

    一个实数,四舍五入保留恰好一位小数,表示最佳快餐店选址距离最远用户的距离

     
    ​4 
    
    1 2 1
    
    1 3 2
    
    2 4 1
    2.0

    题目链接:

    http://qscoj.cn/problem/129/

    题意:

    思路:

    答案就是树的直径/2

    随便拿一个点进行spfa,然后找到离这个点最远的点,又进行一次spfa,然后这个点所得到的最远点,那么这个距离,就是树的直径

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define MS(a) memset(a,0,sizeof(a))
     5 #define MP make_pair
     6 #define PB push_back
     7 const int INF = 0x3f3f3f3f;
     8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     9 inline ll read(){
    10     ll x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 //////////////////////////////////////////////////////////////////////////
    16 const int maxn = 2e5+10;
    17 
    18 struct edge{
    19     int v,w;
    20 };
    21 
    22 vector<edge> g[maxn];
    23 void add_edge(int u,int v,int w){
    24     g[u].push_back((edge){v,w});
    25     g[v].push_back((edge){u,w});
    26 }
    27 
    28 int inq[maxn],d[maxn];
    29 
    30 int main(){
    31     int n = read();
    32     for(int i=0; i<n-1; i++){
    33         int u,v,w;
    34         cin >> u >> v >> w;
    35         add_edge(u,v,w);
    36     }
    37 
    38     for(int i=0; i<=n; i++)
    39         inq[i]=0,d[i]=INF;
    40 
    41     queue<int> q;
    42     q.push(1);
    43     d[1] = 0; inq[1] = 1;
    44 
    45     while(!q.empty()){
    46         int now = q.front(); q.pop();
    47         for(int i=0; i<(int)g[now].size(); i++){
    48             edge e = g[now][i];
    49             if(d[e.v] > d[now]+e.w){
    50                 d[e.v] = d[now]+e.w;
    51                 if(inq[e.v]) continue;
    52                 inq[e.v] = 1;
    53                 q.push(e.v);
    54             }
    55         }
    56     }
    57 
    58     int ans = 0, ans1;
    59     for(int i=1; i<=n; i++){
    60         if(d[i]!=INF && d[i]>ans){
    61             ans = d[i];
    62             ans1 = i;
    63         }
    64     }
    65 
    66     for(int i=0; i<=n; i++)
    67         inq[i]=0,d[i]=INF;
    68 
    69     q.push(ans1);
    70     d[ans1] = 0; inq[ans1] = 1;
    71 
    72     while(!q.empty()){
    73         int now = q.front(); q.pop();
    74         for(int i=0; i<(int)g[now].size(); i++){
    75             edge e = g[now][i];
    76             if(d[e.v] > d[now]+e.w){
    77                 d[e.v] = d[now]+e.w;
    78                 if(inq[e.v]) continue;
    79                 inq[e.v] = 1;
    80                 q.push(e.v);
    81             }
    82         }
    83     }
    84 
    85     ans = 0;
    86     for(int i=1; i<=n; i++){
    87         if(d[i]!=INF && d[i]>ans){
    88             ans = d[i];
    89         }
    90     }
    91 
    92     printf("%.1f
    ",(double)ans*1.0/2);
    93 }
  • 相关阅读:
    SQL字段排序
    delphi MessageBox 用法
    delphi获取当前计算机所有盘符
    PHP限制IP
    delphi 显示数据
    GUI模块分解与开发征集
    delphi 用户登录 代码
    Hello China GUI模块鼠标指针的实现
    DELPHI 托盘 实例
    delphi 内存流 操作
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6837855.html
Copyright © 2020-2023  润新知