题目描述

给定一张有向图,求从1号点出发,每个点能支配的点的个数(包括自己)

输入输出格式

输入格式:

第一行两个正整数n,mn,m,表示点数和边数 接下来mm行,每行输入两个整数u,vu,v,表示有一条uu到vv的有向边

输出格式:

一行输出nn个整数,表示每个点能支配的点的个数

输入输出样例

输入样例#1:

10 15
1 2
2 3
3 4
3 5
3 6
4 7
7 8
7 9
7 10
5 6
6 8
7 8
4 1
3 6
5 3

输出样例#1:

10 9 8 4 1 1 3 1 1 1

思路:求一般有向图的支配点,支配树的 Lengauer Tarjan 算法模板题

源代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<LL,LL>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL quickModPow(LL a,LL b,LL mod){ LL res=1; a=a%mod; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1;} return res; }
LL getInv(LL a,LL mod){ return quickModPow(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 998244353;
const int N = 400000+5;
const int dx[] = {-1,1,0,0,1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;struct MAP {struct Edge {int to, next;} edge[N << 1];int tot, head[N];void addEdge(int x, int y) {edge[++tot].to = y;edge[tot].next = head[x];head[x] = tot;}
};
MAP G, GF;             //原图、反图
MAP dfsTree, dfsTreeF; // dfs树、dfs树的反图
MAP dominate;          //支配树MAP xx;
int n, m;
int father[N];          // dfs树上的父节点
int dfn[N], id[N], tim; // dfs序、标号、时间戳void dfs(int x) {id[++tim] = x;dfn[x] = tim;for (int i = G.head[x]; i; i = G.edge[i].next) {int to = G.edge[i].to;if (!dfn[to]) {dfs(to);father[to] = x;dfsTree.addEdge(x, to);}}
}int sdom[N]; //半支配点
int mn[N]; // mn[i]表示i点的dfs树上的sdom最小的祖先,因此有sdom[mn[i]]=sdom[i]
int anc[N];       // anc[i]代表i的祖先
int find(int x) { //路径压缩的带权并查集if (x != anc[x]) {int t = anc[x];anc[x] = find(anc[x]);if (dfn[sdom[mn[x]]] > dfn[sdom[mn[t]]])mn[x] = mn[t];}return anc[x];
}
void LengauerTarjan() { //寻找半支配点for (int i = 1; i <= n; i++) {anc[i] = i;sdom[i] = i;mn[i] = i;}for (int j = n; j >= 2; j--) {int x = id[j];if (!x)continue;int pos = j;for (int i = GF.head[x]; i; i = GF.edge[i].next) {int y = GF.edge[i].to;if (!dfn[y])continue;if (dfn[y] < dfn[x])pos = min(pos, dfn[y]);else {find(y); //寻找树上y的一个满足dfn[z]>dfn[x]的祖先zpos = min(pos, dfn[sdom[mn[y]]]);}}sdom[x] = id[pos];anc[x] = father[x];dfsTree.addEdge(sdom[x], x); //在dfs树上连边}
}int deep[N], dp[N][25];
int getLCA(int x, int y) { //获取LCAif (deep[x] < deep[y])swap(x, y);int del = deep[x] - deep[y];for (int i = 0; i <= 20; i++)if ((1 << i) & del)x = dp[x][i];if (x == y)return x;for (int i = 20; i >= 0; i--) {if (dp[x][i] != dp[y][i]) {x = dp[x][i];y = dp[y][i];}}return dp[x][0];
}
void buildDominate(int x) { //建立支配树int to = dfsTreeF.edge[dfsTreeF.head[x]].to;for (int i = dfsTreeF.head[x]; i; i = dfsTreeF.edge[i].next) {int y = dfsTreeF.edge[i].to;to = getLCA(to, y);}deep[x] = deep[to] + 1;dp[x][0] = to;dominate.addEdge(to, x);for (int i = 1; i <= 20; i++)dp[x][i] = dp[dp[x][i - 1]][i - 1];
}
int in[N]; // dfs树的入度
void topSort() {for (int i = 1; i <= n; i++) {for (int j = dfsTree.head[i]; j; j = dfsTree.edge[j].next) {int to = dfsTree.edge[j].to;in[to]++;dfsTreeF.addEdge(to, i); //对DFS树的反图建边}}for (int i = 1; i <= n; i++) {if (!in[i]) {dfsTree.addEdge(0, i);  // dfs树建边dfsTreeF.addEdge(i, 0); // dfs树的反图建边}}queue<int> Q;Q.push(0);while (Q.size()) {int x = Q.front();Q.pop();for (int i = dfsTree.head[x]; i; i = dfsTree.edge[i].next) {int y = dfsTree.edge[i].to;if ((--in[y]) <= 0) {Q.push(y);buildDominate(y); //建立支配树}}}
}int idom[N];
void dfsDominate(int x) { //在支配树上搜索idomidom[x] = 1;for (int i = dominate.head[x]; i; i = dominate.edge[i].next) {int y = dominate.edge[i].to;dfsDominate(y);idom[x] += idom[y];}
}
int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++) {int x, y;scanf("%d%d", &x, &y);G.addEdge(x, y);GF.addEdge(y, x);}dfs(1);           // dfs,求出dfs序LengauerTarjan(); //计算半支配点sdomtopSort(); //根据dfs树建立dfs树的反图,并对进行拓扑排序从而建立支配树dfsDominate(0); //在支配树上寻找答案for (int i = 1; i <= n; i++)printf("%d ", idom[i]);printf("\n");return 0;
}

支配树(洛谷-P5180)相关推荐

  1. 信息学奥赛一本通 1365:FBI树(fbi) | 1928:【04NOIP普及组】FBI树 | 洛谷 P1087 [NOIP2004 普及组] FBI 树

    [题目链接] ybt 1365:FBI树(fbi) ybt 1928:[04NOIP普及组]FBI树 洛谷 P1087 [NOIP2004 普及组] FBI 树 [题目考点] 1. 二叉树 [解题思路 ...

  2. 二分答案——砍树(洛谷 P1873)

    题目选自洛谷P1873 分析:如果句子非常低,可以收集到的木材会更多,以至于超过需要的数量.随着砍树高度逐渐增大,获得的木材会逐渐减少.砍树高度增加到一定程度时,收集到的木材就会开始不够用.因此需要找 ...

  3. 线段树 洛谷 p1531 I hate it(I hate it too)

    这里写链接内容 线段树模板 字符串是一个很诡异的问题.... #include<cstdio> #include<iostream> #include<string> ...

  4. 信息学奥赛一本通 1107:校门外的树 | 1931:【05NOIP普及组】校门外的树 | OpenJudge NOI 1.6 06 | 洛谷 P1047 [NOIP2005 普及组] 校门外的树

    [题目链接] ybt 1107:校门外的树 ybt 1931:[05NOIP普及组]校门外的树 OpenJudge NOI 1.6 06:校门外的树 洛谷 P1047 [NOIP2005 普及组] 校 ...

  5. 【学习小记】支配树【图论】

    Preface 给定一个有向图和一个起点 s t st st,我们需要知道起点到某个点的关于必经点的信息. 若起点到点v的所有路径均经过点u,则我们称点u支配点v,显然一个点支配自己本身 顾名思义,支 ...

  6. 洛谷 深基 第1部分 语言入门 第5章 数组与数据批量存储

    P1428 小鱼比可爱 小鱼比可爱 - 洛谷 P1427 小鱼的数字游戏 小鱼的数字游戏 - 洛谷 P5727 [深基5.例3]冰雹猜想 [深基5.例3]冰雹猜想 - 洛谷 P5727 [深基5.例3 ...

  7. 洛谷 P5727 【深基5.例3】冰雹猜想

    C语言基础系列文章 C语言 五种方法输出100以内的素数(质数) 源码 C语言分支结构超基础编程习题整理 详细分析附源码 C语言题解 洛谷P1614 爱与愁的心痛 详细分析源码 C语言题解 P5719 ...

  8. 洛谷 P2597 灾难(支配树)

    题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过生物的阿米巴告 ...

  9. 【洛谷5284】[十二省联考2019] 字符串问题(后缀树优化建边)

    题目: 洛谷 5284 分析: 首先不要问我标题里的「后缀树」是什么,我也不会,瞎写的 -- (传说就是反串后缀自动机的 fa 树?) 前置技能:[知识总结]后缀自动机的构建 首先有一个很 naive ...

最新文章

  1. pycharm中导入包失败,如何设置外部模块的路径
  2. jarjar.jar解决jar包版本兼容问题
  3. Java培训教程之对象的创建与使用
  4. Day5---D4:合规和审计管理
  5. 数组对象常用处理方案(算法思路)
  6. 命令行中只用scala来运行一个spark应用
  7. PMP读书笔记(第6章)
  8. .net pdf转图片_在客户端实现PDF转图片
  9. python init main_python 模块中的 __init__.py __main__.py
  10. flash spi w25q128 w25q64 w25q32 w25q16 verilog fpga程序代码
  11. Django order by 高级用法
  12. 截止失真放大电路_这些基本放大器的知识,你会了吗?
  13. 怎样能让大腿变细方法 揭秘如何瘦大腿和小腿
  14. 逻辑函数的简化之图解法(卡诺图法)
  15. SCAPY官方教程二
  16. TortoiseGit的使用详解
  17. 算法实验之线性规划解决配料问题
  18. 牛客 CMB1 序列找数
  19. Google优化公司采访的最新Google优化资讯报道
  20. 腾讯云服务器可用区什么意思?

热门文章

  1. 设计模式学习之单件模式singleton
  2. 豆瓣9.0,35万读者“搜不到信息”的神秘作者,我们帮你找到了
  3. 父亲节,来认识一下这几位“爸爸”
  4. Simulink之相控整流电路的组合
  5. OneNand、Nand和Nor三种Flash的区别
  6. STM32之串口例程
  7. 查询ElasticSearch:用SQL代替DSL
  8. Java程序员必备:常见OOM异常分析
  9. 什么?你项目还在用Date表示时间?!
  10. Linux 内核维护缺后浪,前浪Linus缺点Fun