这个题乱七八糟的,和之前的灭绝树有点像,但是不一样。那个是DAG,这个是有向图。简单步骤就是先求出来dfs序,然后求出半支配点(?),然后通过这个求支配点。

算法不是很理解,先放在这。

题干:

题目背景

模板题,无背景
题目描述 给定一张有向图,求从1号点出发,每个点能支配的点的个数(包括自己)
输入输出格式
输入格式: 第一行两个正整数n,mn,mn,m,表示点数和边数 接下来mmm行,每行输入两个整数u,vu,vu,v,表示有一条uuu到vvv的有向边 输出格式: 一行输出nnn个整数,表示每个点能支配的点的个数

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = 1e6 + ;
int dfn[N],n,m;
struct node
{
int l,r,nxt;
}a[N << ],b[N << ],c[N << ];
int len = ,len1 = ,lst[N],pre[N],len2 = ,lat[N];
void add(int x,int y)
{
a[++len].l = x;
a[len].r = y;
a[len].nxt = lst[x];
lst[x] = len;
}
void dda(int x,int y)
{
b[++len1].l = x;
b[len1].r = y;
b[len1].nxt = pre[x];
pre[x] = len1;
}
void add1(int x,int y)
{
c[++len2].l = x;
c[len2].r = y;
c[len2].nxt = lat[x];
lat[x] = len2;
}
int sdom[N],bel[N],id[N],val[N],cnt = ;
int fa[N],tot = ,idom[N];
void dfs(int now)
{
dfn[now] = ++cnt;
id[cnt] = now;
for(int k = lst[now];k;k = a[k].nxt)
{
int y = a[k].r;
if(dfn[y]) continue;
dfs(y);
fa[y] = now;
}
}
int find(int x)
{
if(x == bel[x]) return x;
int root = find(bel[x]);
if(dfn[sdom[val[bel[x]]]] < dfn[sdom[val[x]]])
val[x] = val[bel[x]];
return bel[x] = root;
}
/*int find(int x)
{
if(x==bel[x]) return x;
int root=find(bel[x]);
if(dfn[sdom[val[bel[x]]]]<dfn[sdom[val[x]]])
val[x]=val[bel[x]];
return bel[x]=root;
}*/
void tarjan()
{
for(int i = cnt;i >= ;i--)
{
int now = id[i];
for(int k = pre[now];k;k = b[k].nxt)
{
int y = b[k].r;
if(!dfn[y]) continue;
find(y);
if(dfn[sdom[val[y]]] < dfn[sdom[now]])
sdom[now] = sdom[val[y]];
}
add1(sdom[now],now);
bel[now] = fa[now];
now = fa[now];
for(int k = lat[now];k;k = c[k].nxt)
{
int v = c[k].r;
find(v);
if(sdom[val[v]] == now) idom[v] = now;
else idom[v] = val[v];
}
}
for(int i = ,now;i <= cnt;i++)
{
now = id[i];
if(idom[now] != sdom[now])
idom[now] = idom[idom[now]];
}
}
int ans[N];
void dfs_ans(int now)
{
ans[now] = ;
for(int k = lst[now];k;k = a[k].nxt)
{
int y = a[k].r;
dfs_ans(y);
ans[now] += ans[y];
}
}
int main()
{
read(n);read(m);
duke(i,,m)
{
int x,y;
read(x);read(y);
add(x,y);dda(y,x);
}
duke(i,,n)
{
sdom[i] = bel[i] = val[i] = i;
}
dfs();
tarjan();
len = ;
clean(lst);
for(int i = ;i <= n;i++)
if(idom[i]) add(idom[i],i);
dfs_ans();
duke(i,,n)
{
printf("%d ",ans[i]);
}
return ;
}

P5180 【模板】支配树的更多相关文章

  1. [HDU]4694 Important Sisters(支配树)

    支配树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...

  2. P5180-[模板]支配树

    正题 题目链接:https://www.luogu.com.cn/problem/P5180 题目大意 给出\(n\)个点的一张有向图,求每个点支配的点数量. \(1\leq n\leq 2\time ...

  3. P3384 【模板】树链剖分

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  4. 洛谷P3368 【模板】树状数组 2

    P3368 [模板]树状数组 2 102通过 206提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 如题,已知一个数列,你需要进行下面两 ...

  5. 洛谷P3374 【模板】树状数组 1

    P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两 ...

  6. hdu 1754 I Hate It (模板线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others)    M ...

  7. 康复计划#4 快速构造支配树的Lengauer-Tarjan算法

    本篇口胡写给我自己这样的老是证错东西的口胡选手 以及那些想学支配树,又不想啃论文原文的人- 大概会讲的东西是求支配树时需要用到的一些性质,以及构造支配树的算法实现- 最后讲一下把只有路径压缩的并查集卡 ...

  8. luogu3384 【模板】树链剖分

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  9. luogu2597-[ZJOI2012]灾难 && DAG支配树

    Description P2597 [ZJOI2012]灾难 - 洛谷 | 计算机科学教育新生态 Solution 根据题意建图, 新建一个 \(S\) 点, 连向每个没有入边的点. 定义每个点 \( ...

  10. HDU.4694.Important Sisters(支配树)

    HDU \(Description\) 给定一张简单有向图,起点为\(n\).对每个点求其支配点的编号和. \(n\leq 50000\). \(Solution\) 支配树. 还是有点小懵逼. 不管 ...

随机推荐

  1. Linux—Ubuntu14.0.5配置JAVA环境

    1. 前往ORACLE官网下载最新版本的Java JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html,默认下载 ...

  2. 1007 Maximum Subsequence Sum (PAT(Advance))

    1007 Maximum Subsequence Sum (25 分)   Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A ...

  3. buf.writeUInt16BE()

    buf.writeUInt16BE(value, offset[, noAssert]) buf.writeUInt16LE(value, offset[, noAssert]) value {Num ...

  4. Andrew and Chemistry(树的同构)

    Andrew and Chemistry(树的同构) 题链 将一棵树转化为最小表示法,将此时的树哈希一下,同时用map进行标记,就可以判断树是否存在同构 #include <map> #i ...

  5. 【OpenCV, MFC】利用MFC和OpenCV通过系统对话框打开和保存图片

    打开图片: void CImageProDlg::OnImageopen() { // TODO: 在此添加命令处理程序代码 Invalidate(); CFileDialog dlg(TRUE, N ...

  6. noip模拟赛 洗澡

    分析:首先肯定是要用线性筛把素数全部给筛出来的,然后可以维护一个前缀和数组记录1~i个素数的和,对于每一个询问可以从n到1+k枚举它的右端点,然后利用前缀和统计一个长度为K的区间和,看看是不是满足条件 ...

  7. vue.js组件之间通讯--父组件调用子组件的一些方法,子组件暴露一些方法,让父组件调用

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Code(poj 17801)

    求出一个长度为10^n+n-1的序列,其中包含了所有的n位数(一共10^n个数,从00000(n个0)~10^n-1) /* 典型的欧拉回路题目 对于n=4为密码想要序列最短 那么 1234 234? ...

  9. 洛谷(cogs 1293/bzoj 1212) P2292 [HNOI2004]L语言

    1293. [HNOI2004] L语言 ★★★   输入文件:language.in   输出文件:language.out   简单对比时间限制:1 s   内存限制:162 MB [题目描述] ...

  10. linux top进程状态D

    什么是D状态 运行在KVM虚拟机里的一些进程突然出了问题,这些出了问题的进程无法用kill杀掉,使用ps可以看到这些进程处于D状态: [build@kbuild-john ~]$ ps -a -o p ...