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

    Description

    Input

    第一行是两个整数N(3  N  200000)和M,分别表示居住点总数和街道总数。以下M行,每行给出一条街道的信息。第i+1行包含整数Ui、Vi、Ti(1Ui, Vi  N,1  Ti  1000000000),表示街道i连接居住点Ui和Vi,并且经过街道i需花费Ti分钟。街道信息不会重复给出。

    Output

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

    Sample Input

    4 3
    1 2 1
    2 3 1
    3 4 1

    Sample Output

    4


    肯定会选树的直径,然后其他点枚举一下,取到直径两端距离的最小值的最大值,然后加上树的直径就是答案。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define int long long
    #define g getchar()
    #define i isdigit(ch)
    inline int read(){
        int res=0;char ch=g;
        while(!i) ch=g;
        while(i) {res=(res<<3)+(res<<1)+(ch^48);ch=g;}
        return res;
    }
    #undef g
    #undef i
    #define N 200005
    int n, m;
    struct edge{
        int nxt, to, val;
    }ed[N*2];
    int head[N], cnt;
    inline void add(int x, int y, int z)
    {
        ed[++cnt] = (edge){head[x], y, z};
        head[x] = cnt;
    }
    
    int dis[N], disa[N], disb[N];
    int p1, p2;
    int ans1, ans2;
    bool ex[N];
    
    void dfs(int x)
    {
        ex[x] = 1;
        for (int i = head[x] ; i ; i = ed[i].nxt)
        {
            int to = ed[i].to;
            if (ex[to]) continue;
            dis[to] = dis[x] + ed[i].val;
            dfs(to);
        }
    }
    
    inline void SPFA1(int cur)
    {
        memset(ex, 0, sizeof ex);
        memset(disa, 0x3f, sizeof disa);
        disa[cur] = 0;
        queue <int> q;
        q.push(cur);
        while(!q.empty())
        {
            int x = q.front();q.pop();
            ex[x] = 0;
            for (int i = head[x] ; i ; i = ed[i].nxt)
            {
                int to = ed[i].to;
                if (disa[to] > disa[x] + ed[i].val)
                {
                    disa[to] = disa[x] + ed[i].val;
                    if (!ex[to])
                    {
                        ex[to] = 1;
                        q.push(to);
                    }
                }
            }
        }
    }
    
    inline void SPFA2(int cur)
    {
        memset(ex, 0, sizeof ex);
        memset(disb ,0x3f, sizeof disb);
        disb[cur] = 0;
        queue <int> q;
        q.push(cur);
        while(!q.empty())
        {
            int x = q.front();q.pop();
            ex[x] = 0;
            for (int i = head[x] ; i ; i = ed[i].nxt)
            {
                int to = ed[i].to;
                if (disb[to] > disb[x] + ed[i].val)
                {
                    disb[to] = disb[x] + ed[i].val;
                    if (!ex[to])
                    {
                        ex[to] = 1;
                        q.push(to);
                    }
                }
            }
        }
    }
    
    signed main()
    {
        n = read(),m = read();
        for (int i = 1 ; i <= m ; i ++)
        {
            int x = read(), y = read(), z = read();
            add(x, y, z), add(y, x, z);
        }
        dfs(1);
        p1 = 1;
        for (int i = 1 ; i <= n ; i ++) if (dis[i] > dis[p1]) p1 = i;
        memset(dis, 0, sizeof dis);
        memset(ex, 0, sizeof ex);
        dfs(p1);
        p2 = 1;
        for (int i = 1 ; i <= n ; i ++) if (dis[i] > dis[p2]) p2 = i;
        SPFA1(p1);
        SPFA2(p2);
        ans1 = disa[p2];
        for (int i = 1 ; i <= n ; i ++)
            ans2 = max(ans2, min(disa[i], disb[i]));
        printf("%lld
    ", ans1 + ans2);    
        return 0;
    }
  • 相关阅读:
    制作类似QQ截图软件
    XML文件与实体类的互相转换
    MFC中真彩工具条的制作方法
    MFC使用技巧集锦(1)(转载)
    抽象工厂模式与工厂方法模式区别
    VC数据库编程分析
    如何让工具条显示256色图像
    华为软件编程规范和范例
    设计模式总结性试题
    VC++中基于ADO操作ACCESS数据库,FLEXGRID控件的综合应用
  • 原文地址:https://www.cnblogs.com/BriMon/p/9404204.html
Copyright © 2011-2022 走看看