这个题乱七八糟的,和之前的灭绝树有点像,但是不一样。那个是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. CAD得到指定条件的实体

    主要用到函数说明: IMxDrawSelectionSet::Select2 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARI ...

  2. Redis系列(六)--为什么这么快?

    Redis作为一个基于key-value的NoSQL数据库,最显著的特点存取速度非常快,官方说可以达到10W OPS,但是Redis为何这么快? 1.开发语言 Redis使用C语言进行编写的,而Uni ...

  3. TP中U方法详解

    U方法常用于ThinkPHP里的页面跳转 官方称为url组装, 就是根据某种规则组成一个url地址,这个功能就叫组装. 在ThinkPHP里,系统提供了一个封装的函数来处理url的组装,俗称U方法. ...

  4. php第三十节课

    文件操作 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  5. C++ Primer(第4版)-学习笔记-第4部分:面向对象编程与泛型编程

    第15章 面向对象编程OOP(Object-oriented programming)           面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.      在 C++ 中,用类进行 ...

  6. java开发掌握的Linux命令

    linux命令是对Linux系统进行管理的命令.对于Linux系统来说,无论是中央处理器.内存.磁盘驱动器.键盘.鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命 ...

  7. try catch影响Spring事务吗?

    对于这个问题有两种情况: 1.catch只打印异常,不抛出异常 try { 数据库做添加订单表; /; 数据库减少库存; }catch (Exception e){ e.printStackTrace ...

  8. JS中遍历EL表达式中后台传过来的Java集合

    前言:在我的项目里有这么一个情况,后台直接model.addAttribute()存储了一个对象,此对象内部有一个集合,前端JSP处理的方法正常情况下就是直接使用EL表达式即可.但是如果在JS中需要使 ...

  9. Python数据分析与展示(1)-数据分析之表示(2)-NumPy数据存取与函数

    NumPy数据存取与函数 数据的CSV文件存取 CSV文件 CSV(Comma-Separated Value,逗号分隔值) CSV是一种常见的文件格式,用来存储批量数据. 将数据写入CSV文件 np ...

  10. mesh topology for airfoil, wing, blade, turbo

    ref Ch. 5, Anderson, CFD the basics with applications numerical grid generation foundations and appl ...