HDU 3804 Query on a tree 非递归深搜 STL应用
2011-03-30 16:14
85 查看
题意:
给定一颗树,边有权值,有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
;
vector<que> query;
vector<int> hasq
;
stack<res> stk;
multiset<int> v;
multiset<int>::iterator it;
bool instack
;
int iv
;
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;
}
给定一颗树,边有权值,有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
;
vector<que> query;
vector<int> hasq
;
stack<res> stk;
multiset<int> v;
multiset<int>::iterator it;
bool instack
;
int iv
;
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;
}
相关文章推荐
- hdu_3804_Query on a tree(树链剖分)
- hdu_3804_Query on a tree(树链剖分)
- HDU 3804 Query on a tree 树链剖分 + 线段树离线操作 好题
- Hdu 3804 Query on a tree 树链剖分+线段树
- HDU 3804 Query on a tree (树链剖分)
- hdu 3804 Query on a tree (树链剖分+线段树)
- HDU - 3804:Query on a tree(线段树+离线+树链剖分)
- HDU 3804 Query on a tree (树链剖分+离线处理)
- hdu 3804 Query on a tree
- Query on a tree(hdu 3804 树链剖分+线段树 vector)
- HDU 6191 && 2017广西邀请赛:Query on A Tree(字典树启发式合并)
- HDU - 6191 Query on A Tree(可持久化字典树)
- hdoj 3804 Query on a tree 【树链剖分 + 思维】
- HDU 3801 Query on a tree(树链剖分离线处理)
- HDU - 6191 Query on A Tree 可持久化字典树+dfs序
- hdu 6191 Query on A Tree(字典树启发式合并(动态建树) 可持久化字典树+dfs序)
- HDU - 6191 - Query on A Tree (可持久化Trie)
- 3804 Query on a tree
- HDU 6191 Query on A Tree ( DFS序 + 可持久化字典树 )
- hdu 4836 The Query on the Tree(线段树or树状数组)