[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\n",ans);
        
        return 0;
    
}

 

posted @ 2018-07-28 15:37  evenbao  阅读(119)  评论(0编辑  收藏  举报