• [NOIP 2007] 树网的核


    [题目链接]

                https://www.lydsy.com/JudgeOnline/problem.php?id=1999

    [算法]

              树的直径 + 单调队列

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 500010
    const int INF = 2e9;
    
    int i,n,s,ans,head,tail,m,t,tot,u,v,w,l,r;
    int pre[MAXN],dis[MAXN],h[MAXN],f[MAXN],mx[MAXN],q[MAXN];
    bool visited[MAXN];
    
    struct edge
    {
            int to,w,nxt;
    } e[MAXN << 1];
    vector< pair<int,int> > path;
    
    inline void addedge(int u,int v,int w)
    {
            tot++;
            e[tot] = (edge){v,w,h[u]};
            h[u] = tot; 
    }
    inline int bfs(int s)
    {
            int i,cur,v,w,m;
            queue< int > q;
            q.push(s);
            dis[s] = 0;
            pre[s] = 0;
            while (!q.empty())
            {
                    cur = q.front();
                    q.pop();
                    for (i = h[cur]; i; i = e[i].nxt)
                    {
                            v = e[i].to;
                            w = e[i].w;
                            if (!dis[v] && v != s)
                            {
                                    dis[v] = dis[cur] + w;
                                    q.push(v);
                                    pre[v] = cur;
                            }
                    }
            }
            m = 1;
            for (i = 2; i <= n; i++)
            {
                    if (dis[i] > dis[m])
                            m = i;
            }
            return m;
    }
    inline void bfsII(int s)
    {
            int i,cur,v,w;
            queue< int > q;
            q.push(s);
            while (!q.empty())
            {
                    cur = q.front();
                    q.pop();
                    for (i = h[cur]; i; i = e[i].nxt)
                    {
                            v = e[i].to;
                            w = e[i].w;
                            if (!visited[v] && !f[v])
                            {
                                    visited[v] = true;
                                    f[v] = f[cur] + w;
                                    mx[s] = max(mx[s],f[v]);
                                    q.push(v);
                            }
                    }
            }
    }
    int main() 
    {
            
            scanf("%d%d",&n,&m);
            for (i = 1; i < n; i++)
            {
                    scanf("%d%d%d",&u,&v,&w);
                    addedge(u,v,w);
                    addedge(v,u,w);        
            }    
            s = bfs(1); 
            memset(dis,0,sizeof(dis));
            t = bfs(s);
            for (i = t; i; i = pre[i]) visited[i] = true;
            for (i = t; i; i = pre[i]) bfsII(i);
            q[1] = t;
            l = r = t;
            head = tail = 1;
            ans = INF;
            for (l = t; l; l = pre[l])
            {
                    while (pre[r] && dis[l] - dis[pre[r]] <= m)
                    {
                            r = pre[r];
                            while (head <= tail && mx[q[tail]] <= mx[r]) tail--;
                            q[++tail] = r;
                            ans = min(ans,max(mx[q[head]],max(dis[r] - dis[s],dis[t] - dis[l])));
                    }
                    if (q[head] == l) head++;
            }
            printf("%d
    ",ans);
            
            return 0;
        
    }
  • 相关阅读:
    mysql左连接、右连接、内连接之间的区别与联系
    mysql开窗函数
    mysql左连接、右连接、内连接之间的区别与联系
    程序中批处理增删改的一些建议
    event.target/srcElement一点应用
    委托内部机制
    【转载】【重学计算机】计算机组成原理
    redis的几种集群方式
    C++ explicit关键字详解
    hash表开放定址法
  • 原文地址:https://www.cnblogs.com/evenbao/p/9382183.html
Copyright © 2020-2023  润新知