HDU 3804 Query on a tree 非递归深搜 STL应用

来源:互联网 发布:得到网站源码有什么用 编辑:程序博客网 时间:2024/04/29 00:15

题意:

 给定一颗树,边有权值,有q个查询,每次查询,x,y求1到x直接的所有不大于y的边的最大值.

题解:

 离线,先读入所有查询,再深度遍历这棵树,遍历到一条边就把边的权值扔到set里,返回的时候再把这条边的权值删掉.

 如果遍历到的当前点有询问,则对set进行upbounder,找到比当前y大的第一个位置,对迭代器--即可.

/* 

 * File:   main.cpp

 * Author: swordholy

 *

 * Created on 2011年3月30日, 下午2:00

 */

#include <cstdlib>

#include <iostream>

#include <stdio.h>

#include <memory.h>

#include <set>

#include <vector>

#include <stack>

#include <iterator>

using namespace std;

#define N 100005

struct res

{

    int i,x;

};

struct pt

{

    int p,v;

};

struct que

{

    int x,y,ans;

};

vector<pt> a[N];

vector<que> query;

vector<int> hasq[N];

stack<res> stk;

multiset<int> v;

multiset<int>::iterator it;

bool instack[N];

int iv[N];

int main(int argc, char** argv)

{

    int tcase,i,j,n,q,x,y,w;

    scanf("%d",&tcase);

    while(tcase--)

    {

        scanf("%d",&n);

        for(i=1;i<=n;i++)

            a[i].clear();

        iv[1]=-1;

        for(i=1;i<=n-1;i++)

        {

            scanf("%d%d%d",&x,&y,&w);

            iv[y]=w;

            pt temp;

            temp.p=y;

            temp.v=w;

            a[x].push_back(temp);

            temp.p=x;

            temp.v=w;

            a[y].push_back(temp);

        }

        scanf("%d",&q);

        for(i=1;i<=n;i++)

            hasq[i].clear();

        for(i=1;i<=q;i++)

            query.clear();

        for(i=1;i<=q;i++)

        {

            scanf("%d%d",&x,&y);

            que temp;

            temp.x=x;

            temp.y=y;

            temp.ans=-1;

            query.push_back(temp);

            hasq[x].push_back(query.size()-1);

        }

        v.clear();

        v.insert(-1);

        v.insert(-1);

        v.insert(-1);

        while(!stk.empty()) stk.pop();

        memset(instack,0,sizeof(instack));

        res temp;

        temp.x=1;

        temp.i=0;

        instack[1]=1;

        stk.push(temp);

        while(!stk.empty())

        {

            res now=stk.top();

            stk.pop();

            if (now.i==0)

            {

                if (hasq[now.x].size()>0)

                    for(int i=0;i<hasq[now.x].size();i++)

                    {

                        int qi=hasq[now.x][i];

                        int qx=query[qi].x;

                        int qy=query[qi].y;

                        int ans;

                        it=v.upper_bound(qy);

                        it--;

                        ans=(*it);

                        query[qi].ans=ans;

                    }

            }

            if (now.i==a[now.x].size()) {v.erase(v.find(iv[now.x]));continue;}   

            now.i++;

            stk.push(now);

            res next;

            next.i=0;

            next.x=a[now.x][now.i-1].p;

            if (!instack[next.x])

            {

              v.insert(a[now.x][now.i-1].v);

              stk.push(next);

              instack[next.x]=1;

            }

        }

        for(i=0;i<query.size();i++)

            printf("%d/n",query[i].ans);

    }

    return 0;

}

 

原创粉丝点击