HDU 6203 ping ping ping (LCA+DFS序)
2017-09-11 23:34
337 查看
思路参考:http://blog.csdn.net/DorMOUSENone/article/details/77929604
题意:
n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连通。问无法通行的点最少有多少个。
思路:
思路同参考博客。本人手拙,用线段树维护的LCA询问,代码更长一些。
看到这题想到的是LCA+树链剖分,原理相同,排序LCA后,查询链上是否有坏点,但实现起来实在麻烦。同样是对于祖先信息的维护和查询,DFS序就简单许多。
代码:
题意:
n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连通。问无法通行的点最少有多少个。
思路:
思路同参考博客。本人手拙,用线段树维护的LCA询问,代码更长一些。
看到这题想到的是LCA+树链剖分,原理相同,排序LCA后,查询链上是否有坏点,但实现起来实在麻烦。同样是对于祖先信息的维护和查询,DFS序就简单许多。
代码:
#include <bits/stdc++.h> using namespace std; #define ls l,mid,rt*2 #define rs mid+1,r,rt*2+1 #define mi (l+r)/2 const int MAXN=1e4+7; const int INF=0x3f3f3f3f; typedef struct Node{ int x,y,lca; bool operator < (const Node &a)const{ return lca>a.lca; } }Node; Node nodes[MAXN*5]; int anspos,n,m,in[MAXN],out[MAXN],order[2*MAXN],depth[MAXN],cnt,tree[MAXN*8],minn,st,en; bool lazy[MAXN*4]; vector<int> edge[MAXN]; void ini(){ depth[0]=0;cnt=0; for(int i=0;i<=n;i++) edge[i].clear(); } void dfs1(int pos,int fa){ int len=edge[pos].size(); order[++cnt]=pos; in[pos]=cnt; for(int i=0;i<len;i++){ if(edge[pos][i]!=fa){ depth[edge[pos][i]]=depth[pos]+1; dfs1(edge[pos][i],pos); order[++cnt]=pos; } } return ; } void dfs2(int pos,int fa){ int len=edge[pos].size(); in[pos]=++cnt; for(int i=0;i<len;i++){ if(edge[pos][i]!=fa){ dfs2(edge[pos][i],pos); } } out[pos]=cnt; } void push_down2(int rt){ if(lazy[rt]) lazy[rt*2]=lazy[rt*2+1]=1; } void push_up1(int rt){ tree[rt]=min(tree[rt*2],tree[rt*2+1]); } void build1(int l,int r,int rt){ if(l==r){ tree[rt]=depth[order[l]]; return ; } int mid=mi; build1(ls);build1(rs);push_up1(rt); } void build2(int l,int r,int rt){ lazy[rt]=0; if(l==r){ return ; } int mid=mi; build2(ls);build2(rs); } void update2(int l,int r,int rt){ if(l>en||r<st) return ; if(st<=l&&r<=en){ lazy[rt]=1; return ; } int mid=mi; update2(ls); update2(rs); // push_up2(rt); } void query1(int l,int r,int rt){ if(l>en||r<st) return ; if(st<=l&&r<=en){ if(tree[rt]>minn) return ; minn=tree[rt]; } if(l==r){ anspos=l; return ; } int mid=mi; query1(ls);query1(rs); } bool query2(int l,int r,int rt){ if(l>en||r<st) return 0; if(lazy[rt]) return 1; if(l==r) return 0; push_down2(rt); int mid=mi; return query2(ls)||query2(rs); } int main(){ while(scanf("%d",&n)!=-1){ ini(); for(int i=1;i<=n;i++){int x,y; scanf("%d%d",&x,&y); edge[x].push_back(y); edge[y].push_back(x); } dfs1(0,-1); build1(1,cnt,1); scanf("%d",&m); for(int i=0;i<m;i++){int x,y; scanf("%d%d",&x,&y); st=in[x];en=in[y];minn=INF; if(st>en) swap(st,en); query1(1,cnt,1); nodes[i]={x,y,order[anspos]}; } sort(nodes,nodes+m); int ans=0;cnt=0; dfs2(0,-1); build2(1,cnt,1); for(int i=0;i<m;i++){ st=en=in[nodes[i].x]; if(!query2(1,cnt,1)){ st=en=in[nodes[i].y]; if(!query2(1,cnt,1)){ ans++; st=in[nodes[i].lca]; en=out[nodes[i].lca]; update2(1,cnt,1); } } } cout<<ans<<endl; } }
相关文章推荐
- HDU 6203 ping ping ping lca 线段树成段更新
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
- HDU 6203 ping ACM/ICPC 2017 Shenyang Online(LCA+贪心)
- HDU 6203 ping ping ping(在线倍增LCA+BIT)
- HDU 6203 ping ping ping (LCA + 树状数组, 2017 ACM/ICPC Asia Regional Shenyang Online)
- HDU 6203 ping ping ping [LCA+dfs序+树状数组]
- hdu 6203 ping ping ping(LCA+树状数组)
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
- HDU2874——Connections between cities 详解 (LCA,RMQ,数据结构,dfs序,并查集)
- hdu 2874 Connections between cities LCA || dfs+并查集
- hdu----(2586)How far away ?(DFS/LCA/RMQ)
- HDU 6203 ping ping ping
- 多校第一场 1009 hdu 5296 Annoying problem(dfs序+在线倍增lca)
- HDU-4409 Family Name List LCA求解,TC+DFS || tarjan
- HDU 6203 ping ping ping(dfs序+LCA+树状数组)
- hdu 5044 树区间操作最后输出/ lca+dfs
- [HDU 5927] Auxiliary Set (DFS+树上LCA)
- [HDU 6203] ping ping ping
- hdu 5296 Annoying problem(15多校第一场1009)(在线lca+dfs序)
- HDU 3078 - Network (LCA)【tarjan离线/DFS倍增】