zoukankan      html  css  js  c++  java
  • POJ 3162 Walking Race(树的直径+单调队列)

    题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的区间,使得区间中的最大值与最小值的差不超过m。

    思路:先找出树的直径的两个端点来,那么树当中的其它节点能走的最大距离一定是到这个两个点当中的其中一个的。所以三遍bfs就可以求出来这个最远的距离,那么,这个最远的距离求出来之后再用两个单调队列来维护最大值和最小值。

    /*************************************************************************
        > File Name:            poj_3162.cpp
        > Author:               Howe_Young
        > Mail:                 1013410795@qq.com
        > Created Time:         2015年09月05日 星期六 14时00分47秒
     ************************************************************************/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #include <queue>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e6 + 10;
    int tot, head[maxn];
    struct Edge {
        int to, next, w;
    }edge[maxn * 2];
    typedef pair<int, int> pii;
    int dis1[maxn], dis2[maxn], dis[maxn];
    void init()
    {
        tot = 0;
        memset(head, -1, sizeof(head));
    }
    void addedge(int u, int v, int w)
    {
        edge[tot].to = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int pos, maxx;
    bool vis[maxn];
    void bfs(int u, int *dist)//从u点开始搜索到各个点的距离,保存在dist当中
    {
        maxx = 0;
        queue<pii> Q;
        memset(vis, false, sizeof(vis));
        pii cur, nex;
        cur.first = u; cur.second = 0;
        vis[u] = true;
        dist[u] = 0;
        Q.push(cur);
        while (!Q.empty())
        {
            cur = Q.front();
            Q.pop();
            for (int i = head[cur.first]; i != -1; i = edge[i].next)
            {
                int v = edge[i].to;
                if (vis[v]) continue;
                vis[v] = true;
                nex.first = v; nex.second = cur.second + edge[i].w;
                dist[v] = nex.second;
                if (maxx < nex.second)
                {
                    maxx = nex.second;
                    pos = v;//直径的一个端点保存在pos当中
                }
                Q.push(nex);
            }
        }
    }
    int Q_max[maxn], Q_min[maxn];
    int n, m;
    int solve()//用两个单调队列分别维护最大值和最小值
    {
        int ans = 0;
        int front1, front2, tail1, tail2, i, j;
        front1 = front2 = 1; tail1 = tail2 = 0;
        for (j = 1, i = 1; i <= n; i++)
        {
            while (tail1 >= front1 && dis[Q_max[tail1]] <= dis[i]) tail1--;
            Q_max[++tail1] = i;
    
            while (tail2 >= front2 && dis[Q_min[tail2]] >= dis[i]) tail2--;
            Q_min[++tail2] = i;
    
            if (dis[Q_max[front1]] - dis[Q_min[front2]] > m)
            {
                ans = max(ans, i - j);
                while (dis[Q_max[front1]] - dis[Q_min[front2]] > m)
                {
                    j = min(Q_max[front1], Q_min[front2]) + 1;
                    while (tail1 >= front1 && Q_max[front1] < j) front1++;
                    while (tail2 >= front2 && Q_min[front2] < j) front2++;
                }
            }
        }
        ans = max(ans, i - j);
        return ans;
    }
    int main()
    {
        while (~scanf("%d %d", &n, &m))
        {
            int v, w;
            init();
            for (int i = 1; i < n; i++)
            {
                scanf("%d %d", &v, &w);
                addedge(i + 1, v, w);
                addedge(v, i + 1, w);
            }
            bfs(1, dis1);
            bfs(pos, dis1);
            bfs(pos, dis2);
            for (int i = 1; i <= n; i++)
                dis[i] = max(dis1[i], dis2[i]);
            printf("%d
    ", solve());
        }
        return 0;
    }
  • 相关阅读:
    redis之(十二)redis数据的持久化
    redis之(十一)redis实现缓存的功能
    redis之(十)redis实现消息中间件的功能
    redis之(九)redis的事务机制
    SQL关于IN和EXISTS的用法和区别的比较
    mysql explain extra理解
    mysql explain rows理解
    mysql explain中key_len值的说明
    redis常见重要性能指标数据分析和相关问题解决方案
    java.lang.UnsupportedOperationException解决方法!!!
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4783270.html
Copyright © 2011-2022 走看看