hdu 4366 Successor dfs序 + 线段树
来源:互联网 发布:linux下移动文件 编辑:程序博客网 时间:2024/05/21 19:27
大致题意:题目给出一棵树,每个节点有能力值和忠诚度,查询u,就是查询在u的所有子树节点中找一个能力值比u高,(不能相同),而且忠诚度最大的结点。
思路:首先把树状的结构变成线性的,要不然不能利用题目里面的区间性,在子树中查询用到的就是dfs序,重新编号之后,把能力值从大到小排序,(注意一点,为了解决相同的能力值的冲突,在能力值相同的情况下,我是按照dfs序的从小到大排的),然后一个一个先查询,之后再插入。
http://acm.hdu.edu.cn/showproblem.php?pid=4366
#include <map>#include <queue>#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 50005;const int MAXE = 100005;const int INF = 0x3f3f3f3f;struct Row_Edge{ int fa; int lo; int ab; int id;}RE[MAXN];struct Edge { int to; Edge * next;}E[MAXE],*EE;struct Gragh{ int s; int e; int idx; Edge * first;}G[MAXN];struct Node { int x,y; int value; int pos;}t[MAXN<<2];int Q_Array[MAXN];int ANS[MAXN];int n,m;int index = 1;int pos[MAXN];int maxlo,maxpos;void init() { //初始化; EE = E; memset(G,0,sizeof(G)); index = 1;}void addedge(int u,int v) { EE->to = v ; EE -> next = G[u].first; G[u].first = EE ++; EE->to = u ; EE -> next = G[v].first; G[v].first = EE ++;}void dfs(int u,int fa = 0) { //dfs序 //重新编号,找出一个点管辖的是那些点; //G[u]管辖的是从G[u].s 到 G[u].e 的点 pos[index] = u; G[u].idx = index; index ++; G[u].s = index; for(Edge * p = G[u].first ; p ; p = p -> next) { if(p->to != fa) { dfs(p->to,u); } } G[u].e = index - 1;}bool cmp(Row_Edge a1,Row_Edge a2) { if(a1.ab == a2.ab) { //相同的ab值是存在的,脑补出这种方法解决冲突。 return G[a1.id].idx < G[a2.id].idx; } return a1.ab > a2.ab;}void Push_Up(int rt) { if(t[rt<<1].value > t[rt<<1|1].value) { t[rt].pos = t[rt<<1].pos; } else { t[rt].pos = t[rt<<1|1].pos; } t[rt].value = max(t[rt<<1].value,t[rt<<1|1].value);}void Build(int x,int y,int rt) { t[rt].x = x ; t[rt].y = y; if(x == y) { t[rt].value = -1; t[rt].pos = pos[x]; return ; } int mid = (x + y) >> 1; Build(x,mid,rt<<1); Build(mid+1,y,rt<<1|1); Push_Up(rt);}void Update(int rt,int k,int value) { if(t[rt].x == t[rt].y) { t[rt].value = value; t[rt].pos = k; return ; } int mid = (t[rt].x + t[rt].y) >> 1; if(mid >= k) { Update(rt<<1,k,value); } else { Update(rt<<1|1,k,value); } Push_Up(rt);}void Query(int rt,int left,int right) { if(right < left) return ; if(left <= t[rt].x && right >= t[rt].y) { if(t[rt].value > maxlo) { maxlo = t[rt].value; maxpos = t[rt].pos; } return ; } int mid = (t[rt].x + t[rt].y) >> 1; if(mid >= left) { Query(rt<<1,left,right); } if(mid < right) { Query(rt<<1|1,left,right); }}void input() { init(); scanf("%d %d",&n,&m); for(int i = 1 ; i <= n - 1 ; i ++) { scanf("%d %d %d",&RE[i].fa,&RE[i].lo,&RE[i].ab); //存下边的原始条件,因为要排序从大到小一个一个插入; //RE[i].fa i结点的父亲 RE[i].lo i结点的荣誉值 RE[i].ab i结点的能力值; RE[i].id = i; addedge(i,RE[i].fa); //加边,形成一棵树; } for(int i = 1 ; i <= m ; i ++) { scanf("%d",&Q_Array[i]); //查询的序列; }}void solve() { Build(1,n,1); dfs(0); sort(RE+1,RE+n,cmp); // for(int i = 1 ; i <= n-1 ; i++) { // printf("%d %d %d\n",RE[i].id,RE[i].ab,RE[i].lo); // } //print(); //从大到小排序之后,插入n-1条边; for(int i = 1 ; i <= n - 1 ; i ++) { maxlo = -1; maxpos = -1; Query(1,G[RE[i].id].s,G[RE[i].id].e); //查询从开始到结束的区间,是否存在pos; ANS[RE[i].id] = maxpos; //根据ab值排序,所以应该根据lo的值插入; Update(1,G[RE[i].id].idx,RE[i].lo); } maxlo = -1; maxpos = -1; Query(1,1,n); ANS[0] = maxpos; for(int i = 1 ; i <= m ; i++) { if(ANS[Q_Array[i]] == -1) printf("%d\n",ANS[Q_Array[i]]); else printf("%d\n",pos[ANS[Q_Array[i]]]); }}int main(void) { freopen("a.in","r",stdin); int T; scanf("%d",&T); while(T--) { input(); solve(); } return 0;}
0 0
- hdu 4366 Successor dfs序 + 线段树
- HDU 4366 Successor(线段树 DFS时间戳)
- HDU 4366 Successor 线段树
- hdu 4366 Successor 线段树
- hdu 4366 Successor (线段树xdfs序x排序预处理)
- HDU 4366 Successor(dfn序 + 线段树)
- HDU 4366 Successor(线段树)
- hdu 4366 Successor(线段树)
- [线段数]hdu 4366 Successor
- HDU 4366 Successor [树形转线形+线段树]【数据结构+技巧】
- 【线段树】 HDOJ 4366 Successor
- HDU 4366 (dfs序 线段树)
- hdu 4366(线段树+DFS序)
- HDU 4366 浅谈DFS序+线段树
- Successor (线段树)
- [HDU4366]Successor 线段树
- hdu 4366 Successor
- hdu 4366 Successor
- C# ListView用法详解 很完整
- Android stduio依赖关系
- Struts2 自定义拦截器(easy example)
- datagrid自己的一些操作积累
- 微信支付参数说明
- hdu 4366 Successor dfs序 + 线段树
- 贺利坚练习(7)
- java string
- java中的堆和栈
- git reflog
- inno setup制作安装包的经验
- flask 莫名奇妙的错误 相同的代码上面的会出现网页错位。
- phpexecl导入时空行里面有空格导致导入空数据问题
- php的ci框架 配合phpmailer 发邮件