HDU6203 补题LCA复习+dfs序
来源:互联网 发布:电气接线仿真软件 编辑:程序博客网 时间:2024/05/21 07:07
这个题目其实算是贪心吧,感觉自己贪心有点菜,这几天要把贪心练一下了
建树,dfs什么的就不说了,这里主要讲下思路
就是建完树后,给你两个点
然后求出他们的lca,将这两个点u,v和lca,dlca(lca点的深度)存在一个结构体数组中
然后将这个数组按深度从大到小排序
接着遍历这个数组
每次看u,v有没有访问过,如果有就不管,如果没有,就将他们的lca点拿掉并将lca点的所有子节点记为访问过并且ans++
最后输出ans就好了
其实,为什么这样做可以呢
对于一个u,v,我们要做的就是把他们分开,我们就可以拿掉链接u,v上的点的任意一个就好,那么就会出现一个问题
如果有另外两个点的lca正好经过这一条链,那么如果我只拿掉那个点的lca就好了
如果我们这样排序的话,其实就保证了这种情况,也就是保证了最优
还有一点,我们标记已访问过的点时,不需要用到树链剖分,因为是对子树的操作,dfs序就可以了
这个题目有点手残,用的线段树求的lca,代码量直接爆炸了
#include <iostream>#include <cstring>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 60010using namespace std;struct Edge{ int next,en;};struct Save{ int node,dep; Save(int n,int d){node=n;dep=d;} Save(){}};bool operator < (Save a,Save b){return a.dep<b.dep;}struct Node{ int u,v; Save lca;};bool operator < (Node a,Node b){return a.lca.dep<b.lca.dep;}bool cmp(Node a,Node b){return a.lca.dep>b.lca.dep;}Edge edge[maxn];Node node[maxn];Save save[maxn*2];Save segt[maxn<<2];//线段树的大小为节点大小的4倍int head[maxn],cnte;int dfsx,in[maxn],out[maxn],vis[maxn],cntn;int LCAArray[maxn*2];void init(){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); cnte=0;cntn=0;dfsx=0;}void addedge(int st,int en){ cnte++; edge[cnte].en=en; edge[cnte].next=head[st]; head[st]=cnte; return;}void addnode(int u,int v,Save lca){ cntn++; node[cntn].u=u;node[cntn].v=v; node[cntn].lca=lca; return;}void dfs(int root,int depth)//dfs没问题{ dfsx++; in[root]=dfsx;vis[root]=1; save[dfsx].dep=depth;save[dfsx].node=root; for (int k=head[root];k!=-1;k=edge[k].next) if (!vis[edge[k].en]) { dfs(edge[k].en,depth+1); dfsx++; save[dfsx].dep=depth;save[dfsx].node=root; } out[root]=dfsx; return;}void build(int root,int beg,int en)//线段树建树函数{ if (beg==en) segt[root]=save[beg]; else { build(root*2,beg,(beg+en)/2); build(root*2+1,(beg+en)/2+1,en); if (segt[root*2]<segt[root*2+1]) segt[root]=segt[root*2]; else segt[root]=segt[root*2+1]; } return;}Save query(int root,int l,int r,int ql,int qr){ if(l == ql && r == qr) return segt[root]; int mid=(l+r)/2; if(qr <= mid) return query(root*2,l,mid,ql,qr); else if(ql >= mid + 1) return query(root*2+1,mid+1,r,ql,qr); return min(query(root*2,l,mid,ql,mid), query(root*2+1,mid + 1,r,mid + 1,qr));}void initLCA(int n){ dfs(0,1); build(1,1,dfsx);}Save LCA(int u,int v){ int qbeg,qend; if (in[u]<in[v]) {qbeg=in[u];qend=in[v];} else {qbeg=in[v];qend=in[u];} return query(1,1,dfsx,qbeg,qend);}struct Segt{ int val,addmark;};Segt segtf[maxn<<2];void pushdown(int root){ if (segtf[root].addmark!=0) { segtf[root*2].val+=segtf[root].addmark; segtf[root*2].addmark+=segtf[root].addmark; segtf[root*2+1].val+=segtf[root].addmark; segtf[root*2+1].addmark+=segtf[root].addmark; segtf[root].addmark=0; } return;}int queryf(int root,int l,int r,int poi){ if(l==r) return segtf[root].val; pushdown(root); int mid=(l+r)/2; if(poi <= mid) return queryf(root*2,l,mid,poi); else if(poi >= mid + 1) return queryf(root*2+1,mid+1,r,poi);}void updatef(int root,int rst,int ren,int beg,int en,int val){ if (rst>=beg&&ren<=en) { segtf[root].val+=val; segtf[root].addmark+=val; } else if (rst>en||ren<beg) {return;} else { pushdown(root); int mid=(rst+ren)/2; updatef(root*2,rst,mid,beg,en,val); updatef(root*2+1,mid+1,ren,beg,en,val); segtf[root].val=segtf[root*2].val&&segtf[root*2+1].val; }}int main(){ int n,m; while(~scanf("%d",&n)) { init(); for (int k=1;k<=n;k++) { int st,en; scanf("%d %d",&st,&en); addedge(st,en);addedge(en,st); } n++; initLCA(n); scanf("%d",&m); for (int k=1;k<=m;k++) { int u,v; Save lca; scanf("%d %d",&u,&v); lca=LCA(u,v); addnode(u,v,lca); } sort(node+1,node+1+cntn,cmp); memset(segtf,0,sizeof(segtf)); int ans(0); for (int k=1;k<=cntn;k++) { int u,v,l; u=node[k].u;v=node[k].v;l=node[k].lca.node; if ((queryf(1,1,dfsx,in[u])==0)&&(queryf(1,1,dfsx,in[v])==0)) { ans++; updatef(1,1,dfsx,in[l],out[l],1); } } printf("%d\n",ans); } return 0;}
阅读全文
1 0
- HDU6203 补题LCA复习+dfs序
- HDU6203 ping ping ping 【LCA+BIT】
- [LCA][dfs序]BZOJ 2819: Nim
- [BZOJ2819] Nim && dfs序 + 树状数组 + LCA
- HDU 5296 Annoying problem dfs序+lca
- [Kattis Boxes] 倍增法LCA / DFS序
- HDU 6203 贪心 + LCA + dfs序 + BIT
- 异象石 LCA+Splay+Dfs序 Maverick_Frank
- 倍增LCA复习
- [复习]LCA Tree
- POJ 3417 LCA+DFS
- poj3417Network(LCA+dfs)
- hdu5452(LCA+DFS)
- BZOJ 2819 Nim 树链剖分/DFS序+LCA+树状数组
- BZOJ 3991(dfs序 + LCA 公式推导)
- hdu5458 LCA+并查集+dfs序+树状数组
- hdu_5293_Tree chain problem(DFS序+树形DP+LCA)
- [HDU 5296] Annoying problem (DFS序性质+LCA)
- 开发中遇到的 小坑
- cmake编译opencv链接动态库
- 各种魔术方法,$_SERVER的详细参数与说明
- JAVA面试题
- Combinatory categorial grammar (CCG)
- HDU6203 补题LCA复习+dfs序
- unsigned char* 转qstring
- 加油,你可以的!
- 13. Roman to Integer
- 输入两个链表,找出它们的第一个公共结点
- SpringMVC起步-构建Web应用程序
- 岛国科普第2弹-再造人类生命的神奇细胞Human.Life.Our.Amazing.Cell
- js-时间处理
- 【C++】重载“<<"操作符和关键字static!!!