HDU.4694.Important Sisters(支配树)
\(Description\)
给定一张简单有向图,起点为\(n\)。对每个点求其支配点的编号和。
\(n\leq 50000\)。
\(Solution\)
支配树。
还是有点小懵逼。
不管了,说不定会讲,反正以后再说。
https://blog.csdn.net/litble/article/details/83019578
有图的:https://blog.csdn.net/VioletSu/article/details/81041954
有题的:https://blog.csdn.net/L_0_Forever_LF/article/details/79386508
有怎么卡纯路径压缩并查集的:https://www.cnblogs.com/meowww/archive/2017/02/27/6475952.html
记几个名词:
\(Lengauer\ Tarjan\)算法。
半支配点(\(semi-dominator\)),记作\(semi(x)\)。
最近支配点(\(immediate\ dominator\)),记作\(idom(x)\)。
想不到我竟然也有把if(x==y)
写成if(x=y)
而且还调半天的时候...
//1107MS 8292K
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=50005,M=1e5+5;
int Index,dfn[N],ref[N],F[N],fa[N],mn[N],semi[N],idom[N],Ans[N];
struct Graph
{
int Enum,H[N],nxt[M],to[M];
inline void Clear(int n)
{
Enum=0, memset(H,0,n+1<<2);
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
}G,RG,SG,T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void DFS0(int x)
{
ref[dfn[x]=++Index]=x;
for(int i=G.H[x],v; i; i=G.nxt[i])
if(!dfn[v=G.to[i]]) fa[v]=x, DFS0(v);
}
int Find(int x)
{
if(x==F[x]) return x;
int tmp=F[x];
F[x]=Find(F[x]);
if(dfn[semi[mn[tmp]]]<dfn[semi[mn[x]]]) mn[x]=mn[tmp];
return F[x];
}
void DFS(int x,int s)
{
Ans[x]=s+=x;
for(int i=T.H[x]; i; i=T.nxt[i]) DFS(T.to[i],s);
}
void Solve(int n)
{
for(int k=n; k>1; --k)
{
int x=ref[k],t=n;//求半支配点
for(int i=RG.H[x],v; i; i=RG.nxt[i])
if(dfn[v=RG.to[i]])
if(dfn[v]<dfn[x]) t=std::min(t,dfn[v]);
else Find(v), t=std::min(t,dfn[semi[mn[v]]]);
F[x]=fa[x], SG.AE(semi[x]=ref[t],x);
x=ref[k-1];//从半支配点到支配点
for(int i=SG.H[x],v; i; i=SG.nxt[i])
{
Find(v=SG.to[i]);
if(semi[v]==semi[mn[v]]) idom[v]=semi[v];
else idom[v]=mn[v];//idom[mn[v]]此时可能并未找到
}
}
for(int k=2,x; k<=n; ++k)
{
x=ref[k];
if(idom[x]!=semi[x]) idom[x]=idom[idom[x]];
T.AE(idom[x],x);
}
DFS(n,0);
for(int i=1; i<n; printf("%d ",Ans[i++]));
printf("%d\n",Ans[n]), memset(Ans,0,n+1<<2);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1,u,v; i<=m; ++i) u=read(),v=read(),G.AE(u,v),RG.AE(v,u);
for(int i=1; i<=n; ++i) F[i]=semi[i]=mn[i]=i;
Index=0, DFS0(n), Solve(n);
G.Clear(n), RG.Clear(n), SG.Clear(n), T.Clear(n);
memset(dfn,0,n+1<<2), memset(idom,0,n+1<<2), memset(ref,0,n+1<<2);//, memset(fa,0,n+1<<2);//不都清空会RE啊==
}
return 0;
}
HDU.4694.Important Sisters(支配树)的更多相关文章
- [HDU]4694 Important Sisters(支配树)
支配树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...
- hdu 4694 Important Sisters【支配树】
求出支配树输出到father的和即可 支配树见:https://blog.csdn.net/a710128/article/details/49913553 #include<iostream& ...
- 【23.91%】【hdu 4694】Important Sisters("支NMLGB配树"后记)(支配树代码详解)
Time Limit: 7000/7000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission( ...
- HDOJ Important Sisters
Important Sisters Time Limit: 7000/7000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 5862 Counting Intersections(离散化+树状数组)
HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...
- 康复计划#4 快速构造支配树的Lengauer-Tarjan算法
本篇口胡写给我自己这样的老是证错东西的口胡选手 以及那些想学支配树,又不想啃论文原文的人- 大概会讲的东西是求支配树时需要用到的一些性质,以及构造支配树的算法实现- 最后讲一下把只有路径压缩的并查集卡 ...
- hdu 5517 Triple(二维树状数组)
Triple Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- [hdu4694]Important Sisters
来自FallDream的博客,未经允许,请勿转载,谢谢. 给定一张图,求每个点到第n个点必须经过的点的编号之和.n<=50000 一道支配树裸题 然后统计答案的时候可以正着推,ans[i]=an ...
随机推荐
- IDEA部署项目和多余的项目删掉的演示
- Scrapy库的安装(windows版)
这个是需要安装的所有文件 1. wheel pip install wheel 2. lxml http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 3. P ...
- .NET Framework 类库——C#命名空间大全
引用地址:https://msdn.microsoft.com/zh-cn/library/gg145045.aspx C# using引用时,不知道有哪些命名空间,这下转载收集一篇,方面查找使用. ...
- ElasticSearch简要总览
今天看了一下ElasticSearch的相关文档,我做了如下总结: 发现越来越喜欢画图归纳总结知识了,看图说话 集群特性说明 健康状况的说明 如何配置分片? 接下来一张图总结下操作相关的总结 接下来, ...
- [HNOI2007]梦幻岛宝珠
题解: 一道比较好的题目 首先比较显然的就是我们要按照a*2^b的b的顺序来枚举 那么状态f[i][j]表示当前在b,用了a*2^b 刚开始没想到怎么不同层之间搞 看了题解发现非常简单 由于每一层到最 ...
- 在vs.net 2010,2015 等版本,给JS函数添加代码提示\注释
经常编写JS的朋友常常会因为函数写多了,隔一段时间就会忘记了函数的用途,或者函数里带的参数作用情况,这个时候会联想到VS工具里的强大提示功能,多希望也能在JS上实现呀,告诉你,这个想法并不是多难,VS ...
- 【转】WPF中的窗口的生命周期
原文地址:http://www.cnblogs.com/Jennifer/articles/1997763.html WPF中的窗口的生命周期 WPF中所有窗口的基类型都是System.Windows ...
- lvs - mask标记
将两个服务绑定在一个集群服务中 如何将两种请求绑定在一个集群中通过一个director来调度, 这里需要iptable工具配合实现.首先在prerouting链上做一个标记,通过标记来调度 起两个服务 ...
- Python题目练习(一)
1.使用while循环输入 1 2 3 4 5 6 8 9 10 i = 1 while i <=10 : if i != 7: print(i) else: print(' ') i += ...
- Shell工具| 流程控制
1. 流程控制 if 判断 ()[ 条件判断式 ],中括号和条件判断式之间必须有空格 ()if后要有空格 [kris@hadoop datas]$ vim if.sh #!/bin/bash -eq ...