[学习笔记]支配树

被支配树支配的恐惧

定义

显然,这个支配关系是一个树(或者如果有的点不能从r到达,就是一个树+一堆点)。

首先不会成环,其次也不会是DAG

即如果A支配C,B支配C,那么A和B之间必然有支配关系

解法

首先是DAG很好做:

[ZJOI2012]灾难

一般有向图:有环的存在,不能topo

方法分三步:

转化为找半支配点

idom[x]表示x的支配点编号

sdom[x]表示x的半支配点编号

先找到原图一个生成树,找到每个点的dfn序

 

定义半支配关系为:

定义半支配点为:

即满足支配关系dfn最小的点

 

一些认识:

A对于dfs树

B对于支配和半支配

 

半支配点也一定是x在dfs树上的祖先

 

请大量运用反证法和dfs算法的深度优先性质进行证明

 

虽然sdom[x]可能不是idom[x]

但是可以断言:

证明:

实在不懂可以画图感性理解

 

所以如果知道sdom[x],现在已经可以专化为求DAG的支配树了

 

如何找半支配点

 这个做法就是前面两个认识的两种情况。

dfn[z]>dfn[y]启发我们倒序处理

这样,x在T'的祖先z一定都是之前加入的,一定比y的dfn大,直接取即可。

实现维护T'?

改进:同时找支配点

 

(fix:每个点从一个祖先连过来恰好一条边)

证明略

直接看算法流程吧:

从简化之后的G'角度进行考虑(基本上就是一个树形结构了),就很好理解了。

补充:

第5步之所以找fa[y],因为先有第4步,使得当前的根是fa[y],(4/5两步交换,就可以直接处理sdom[x]=y的点x了)

第6步的标记还原:必须dfs序正序处理。打标记,如果没有idom[x]=sdom[x],那么进行处理。

开始时候,令sdom[x]=x可以省去很多麻烦!!

Code

注意比较函数的书写。argmin与argmax

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}namespace Miracle{
const int N=2e5+5;
const int M=3e5+5;
int n,m;
struct node{int nxt,to;
}e[M];
int hd[N],cnt;
void add(int x,int y){e[++cnt].nxt=hd[x];e[cnt].to=y;hd[x]=cnt;
}
vector<int>mem[N],fr[N];
int fa[N],dfn[N],fdfn[N],idom[N],sdom[N],df;
int gf[N],val[N];
bool cmp(int x,int y){//x<y?return dfn[sdom[x]]<dfn[sdom[y]];
}
int chm(int x,int y){return dfn[x]<dfn[y]?x:y;
}
int fin(int x){if(gf[x]==x) return x;int rt=fin(gf[x]);val[x]=cmp(val[x],val[gf[x]])?val[x]:val[gf[x]];return gf[x]=rt;
}
void dfs(int x){dfn[x]=++df;fdfn[df]=x;for(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;if(dfn[y]) continue;fa[y]=x;dfs(y);}
}
void wrk(){for(reg i=n;i>=2;--i){int x=fdfn[i];for(reg j=0;j<(int)fr[x].size();++j){int y=fr[x][j];if(dfn[y]<dfn[x]){sdom[x]=chm(y,sdom[x]);}else{int haha=fin(y);sdom[x]=chm(sdom[val[y]],sdom[x]);}}mem[sdom[x]].push_back(x);gf[x]=fa[x];x=fa[x];for(reg j=0;j<(int)mem[x].size();++j){int y=mem[x][j];int haha=fin(y);if(sdom[val[y]]==sdom[y]) idom[y]=sdom[y];else idom[y]=val[y];}}for(reg i=2;i<=n;++i){int x=fdfn[i];if(idom[x]!=sdom[x]) idom[x]=idom[idom[x]];}
}
int sz[N];
void sol(int x){sz[x]=1;for(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;sol(y);sz[x]+=sz[y];}
}
int main(){rd(n);rd(m);int x,y;for(reg i=1;i<=m;++i){rd(x);rd(y);add(x,y);fr[y].push_back(x);}dfs(1);    for(reg i=1;i<=n;++i){sdom[i]=i,val[i]=i,gf[i]=i;}wrk();memset(hd,0,sizeof hd);cnt=0;for(reg i=2;i<=n;++i){add(idom[i],i);}// prt(dfn,1,n);// prt(fa,1,n);// prt(sdom,1,n);// prt(idom,1,n);sol(1);prt(sz,1,n);return 0;
}}
signed main(){Miracle::main();return 0;
}/*Author: *Miracle*
*/

例题

其实就是[ZJOI2012]灾难

别的没什么题目。。。。

转载于:https://www.cnblogs.com/Miracevin/p/10819686.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RBAC 权限设计(转载)

来源 &#xff1a;https://blog.csdn.net/rocher88/article/details/43190743 这是我在网上找的一些设计比较好的RBAC权限管理不知道&#xff0c;像新浪、搜狐、网易、百度、阿里巴巴、淘宝网的RBAC用户权限这一块&#xff0c;都是这种细颗粒的RBAC设计开发&#xff0c;还是把他…

54.get set

当程序查询对象属性时调用get方法,如果只有get方法那么他是一个只读属性&#xff0c;//程序对对象属性进行赋值操作时调用set方法&#xff0c;如果只有set方法那么他是是一个只读属性 <script type"text/javascript">var p {x:1.0,y:1.0,//当程序查询对象属性…

Codeforces Round #554 Div.2 E - Neko and Flashback

欧拉路径 神题啊神题&#xff01;这道题的突破口就是后两个数组每个元素是一一对应的。 也就是说&#xff0c;对于一个p的排列&#xff0c;b和c取得每一个元素的下标在p中都是一样的。 根据b和c数组的性质可以得出&#xff0c;b[i] < c[i]。 这也是我们输出-1的一个判断方法…

20172311 2017-2018-2 《程序设计与数据结构》第八周学习总结

20172311 2017-2018-2 《程序设计与数据结构》第八周学习总结 教材学习内容总结 本周对JAVA中的多态性进行了学习 多态性引用能够随时间变化指向不同类型的对象&#xff0c;是通过后绑定实现的。实现多态性的主要途径有两种&#xff1a; 1.由继承实现多态性 2.利用接口实现多态…

Linux系统安装Apache 2.4.6

http://www.cnblogs.com/kerrycode/p/3261101.html Apache简介 Apache HTTP Server&#xff08;简称Apache&#xff09;是Apache软件基金会的一个开放源码的网页服务器&#xff0c;可以在大多数计算机操作系统中运行&#xff0c;由于其多平台和安全性被广泛使用&#xff0c;是最…

深浅拷贝

lst1 ["金毛狮王", "紫衫龙王", "白眉鹰王", "青翼蝠王"] lst2 lst1 print(lst1) print(lst2) lst1.append("杨逍") print(lst1) print(lst2) # 结果: # [金毛狮王, 紫衫龙王, 白眉鹰王, 青翼蝠王, 杨逍] # [金毛狮王 紫衫…

lnmp化境开启pathinfo,支持tp5.0等访问

一、 开启pathinfo   #注释 下面这一行 #include enable-php.conf #载入新的配置文件 include enable-php-pathinfo.conf #添加如下location / {if (!-e $request_filename){rewrite ^/(.*)$ /index.php/$1 last;break;}}location ~ /index.php {fastcgi_pass 127.0.0.1:…

深度解密GO语言之反射

反射和 Interface 息息相关&#xff0c;而 Interface 是我们上一篇文章的内容。在开始正文前&#xff0c;和大家说点题外话。 上一篇关于 Interface 的文章发出后&#xff0c;获得了很多的关注和阅读。比如&#xff0c;登上了 GoCN 的每日新闻第一条&#xff1a; 可能是编辑者觉…

Python爬虫-正则表达式

正则表达式 只提取关注的数据&#xff0c;进行数据赛选 原子&#xff1a; 基本组成单位 普通的字符 非打印支付 通用字符 普通的字符 >>> import re >>> pat"yue" >>> string"http://yum.iqianyue.com" >>> rst1re.se…

openfire(一):使用idea编译openfire4.2.3源码

最近公司项目要使用openfire&#xff0c;并对源码做一些修改&#xff0c;使用的openfire版本为官网目前最新版本4.2.3&#xff0c;网上资料较少&#xff0c;踩了很多坑&#xff0c;特此记录。 1.下载源码 http://www.igniterealtime.org/downloads/source.jsp 2.使用idea导入源…

JAVA synchronized关键字锁机制(中)

synchronized 锁机制简单的用法&#xff0c;高效的执行效率使成为解决线程安全的首选。 下面总结其特性以及使用技巧&#xff0c;加深对其理解。 特性: 1. Java语言的关键字&#xff0c;当它用来修饰一个方法或者一个代码块的时候&#xff0c;能够保证在同一时刻最多只有一个线…

Python多线程豆瓣影评API接口爬虫

爬虫库 使用简单的requests库&#xff0c;这是一个阻塞的库&#xff0c;速度比较慢。 解析使用XPATH表达式 总体采用类的形式 多线程 使用concurrent.future并发模块&#xff0c;建立线程池&#xff0c;把future对象扔进去执行即可实现并发爬取效果 数据存储 使用Python ORM sq…

【自制工具类】Java删除字符串中的元素

这几天做项目需要把多个item的id存储到一个字符串中&#xff0c;保存进数据库。保存倒是简单&#xff0c;只需要判断之前是否为空&#xff0c;如果空就直接添加&#xff0c;非空则拼接个“&#xff0c;” 所以这个字符串的数据结构是这样的 String str "a,b,c,d"; 保…

DMA存储器到外设代码讲解

实验目的: bsp_dma_mtp.h #ifndef __BSP_DMA_MTP_H #define __BSP_DMA_MTP_H#include "stm32f10x.h" #include <stdio.h>// 串口工作参数宏定义 #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USAR…

java基础集合类——LinkedList 源码略读

1.概览 LinkedList是java的动态数组另一种实现方式&#xff0c;底层是基于双向链表&#xff0c;而不是数组。 public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable LinkedLis…

[BZOJ] 1688: [Usaco2005 Open]Disease Manangement 疾病管理

1688: [Usaco2005 Open]Disease Manangement 疾病管理 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 727 Solved: 468[Submit][Status][Discuss]Description Alas! A set of D (1 < D < 15) diseases (numbered 1..D) is running through the farm. Farmer John woul…

es6 var、let、const命令

1.let和var <1>let声明的变量仅在块级作用域内有效&#xff1b; var声明的变量在全局有效&#xff1b; <2> var变量乐意在声明之前使用&#xff0c;输出undefined; let 不可以&#xff0c;直接抛出一个错误&#xff1b; 例如&#xff1a;//var 声明console.log(a);…

实例属性和类属

1.Python是动态语言&#xff0c;根据类创建的实例&#xff0c;可以任意绑定属性 2.给实例绑定属性的方法有两种&#xff1a; 通过实例变量或者通过self变量。 1 class Student(object): 2 def __init__(self, name): 3 self.namename 4 5 ##或者如下&#xff1a; 6 &g…

vim中跳到第一行和最后一行

底线命令模式 :0或:1跳到文件第一行 :$跳到文件最后一行 命令模式 gg跳到第一行 shiftg跳到文件最后一行转载于:https://www.cnblogs.com/liuys635/p/10831196.html

bootstrap-table 刷新页面数据

bom.bootstrapTable(load,msg[object]);//这一步 务必要添加。if(msg[code]1){bom.find(tbody).css(display,table-row-group)bom.bootstrapTable({data: msg[object],columns: columns,resizable: true,cache:false,pagination: true,sidePagination: client,pageNumber: 1,pa…