学习一个支配树
来源:互联网 发布:淘宝推广软件哪个好 编辑:程序博客网 时间:2024/04/28 09:46
前置技能: LCA (Tarjan)
今年冬令营上讲的东西现在才学 惭愧惭愧。。
首先做出图G的dfs树T 其中S为起点
定义T中节点 u 的半必经点sdom[u] 为 u的祖先中能经过若干条非树边到达u的(除了sdom[u]直接引出的边 其余边必须为非树边) 深度最小的节点
则对于任意一条边 (v->u)
这里我们默认sdom idom 记录的是dfn
则有
1.dfn[v]<dfn[u] 即(v->u)为一条树边或前向边 有sdom[u]=Min(dfn[u],sdom[u]);2.dfn[v]>dfn[u] 即(v->u)为横插边或反组边 则有sdom[u]=Min(sdom[u],sdom[x]),x为v->LCA(v,u)的路径节点中sdom最小的节点
以上的式子我们可以利用tarjan的LCA 从dfn为n的节点倒推来做
对于idom我们怎么求呢?
令x为u->sdom[u]路径中sdom最小的节点
1. sdom[u]=sdom[x] idom[u]=sdom[x]2. sdom[u]!= sdom[x] idom[u]=idom[sdom[u]]
同样x的求解过程我们也可以用tarjan的lca求
至此问题完美解决
至于证明。。
sdom的求解可以感性理解一下
idom嘛。。。我也不会
HDU4694
就是很裸的Dominator Tree了。。
就当是模板练习
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>using namespace std;char c;inline bool read(int&a){a=0;do c=getchar();while(c!=EOF&&(c<'0'||c>'9'));if(c==EOF)return false;while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();return true;}const int N=500001;struct Chain{ Chain*next; int u;}*Head[N],*Head2[N],*Head3[N];inline void Add(Chain**Head,int u,int v){ Chain*tp=new Chain;tp->next=Head[u];Head[u]=tp;tp->u=v;}int mn[N],dfn[N],idom[N],sdom[N],id[N],fa[N],f[N];int cnt;int find(int x){ if(f[x]==x)return x; int y=find(f[x]); if(sdom[mn[x]]>sdom[mn[f[x]]])mn[x]=mn[f[x]]; return f[x]=y;}void dfs(int u){ id[dfn[u]=++cnt]=u; for(Chain*tp=Head[u];tp;tp=tp->next) if(!dfn[tp->u])dfs(tp->u),fa[dfn[tp->u]]=dfn[u];}int n,m;inline void tarjan(int s){ for(int i=1;i<=n;i++)f[i]=sdom[i]=mn[i]=fa[i]=i,dfn[i]=0; cnt=0; dfs(s); int k,x; for(int i=cnt;i>1;i--) { for(Chain*tp=Head2[id[i]];tp;tp=tp->next) if(dfn[tp->u]) find(k=dfn[tp->u]),sdom[i]= sdom[i]<sdom[mn[k]]?sdom[i]:sdom[mn[k]]; Add(Head3,sdom[i],i); for(Chain*tp=Head3[f[i]=x=fa[i]];tp;tp=tp->next) find(k=tp->u),idom[k] = sdom[mn[k]] < x?mn[k]:x; Head3[x]=NULL; } for(int i=2;i<=cnt;Add(Head3,id[idom[i]],id[i]),i++) { if(idom[i]!=sdom[i])idom[i]=idom[idom[i]]; //if(idom[i]==i)puts("WA"); }}int Ans[N];void Mp(int u,int p){ Ans[u]=p; for(Chain*tp=Head3[u];tp;tp=tp->next) Mp(tp->u,p+tp->u);}void out(int x){if(!x){putchar('0');return ;}if(x>9)out(x/10);putchar('0'+x%10);}int main(){ while(true) { cnt=0; if(!read(n))break;read(m); memset(Head,0,sizeof(Head)); memset(Head2,0,sizeof(Head2)); memset(Head3,0,sizeof(Head3)); for(int i=1;i<=m;i++){int a,b;read(a),read(b);Add(Head,a,b),Add(Head2,b,a);} tarjan(n); Mp(n,n); for(int i=1;i<=n;i++) out(Ans[i]),putchar(i==n?'\n':' '),Ans[i]=0; } return 0;}
阅读全文
0 0
- 学习一个支配树
- 学习一个支配树
- 支配树学习笔记
- 支配树(dominator tree)学习笔记
- 支配树(Dominator Tree)学习笔记
- 支配树(Dominator tree)学习笔记 及HDU4694Important Sisters
- Codechef GRAPHCNT 支配树学习及tarjan算法求解
- HDU 4694 [支配树]
- 支配树[模板]
- 树的最小支配集
- 支配树 与 tarjan算法
- hdu4694 Important Sisters 支配树
- 树的最小支配集
- bzoj2815 [ZJOI2012]灾难 支配树
- hihocoder #1343 : Stable Members(支配树)
- BJ模拟 医院(支配树DominatorTree)
- HDU4694:Important Sisters(支配树DominatorTree)
- HDU 4694 Important Sisters【支配树】
- 安全自主可控,国产操作系统走向增长之路
- vcf文件格式详细解释
- 在PHP中连接数据库的八大步骤
- 页面中所有受损的图片都替换了
- Unity Shader学习笔记:模糊效果
- 学习一个支配树
- 这个团队厉害啦!只有“程序猿”没有“程序媛”
- Dagger2入门初探
- lucene三---中文分词器
- 3D打印切片软件Cura及CuraEngine原理分析
- 获取图片
- 设计模式的应用场景(21)--备忘录模式
- USB开发基础--USB Monitor2.26 实例讲解USB的枚举(配置)过程
- linux shell编程