耳分解&双极定向&边三连通

一张无向图的最大独立集与最大简单环长度至少有一个 \(\ge \sqrt n\)

耳分解

无向图版本

定义

  1. 耳与开耳

    在无向图 \(G=(V,E)\) 中存在子图 \(G'=(V',E')\),若简单路径或简单环 \(P:x_1\to x_2\to \dots \to x_d\) 满足 \(x_1,x_d\in V',x_2,\dots x_{d-1}\notin V'\),则称 \(P\)\(G\) 关于 \(G'\) 的耳,若 $P $ 是简单路径,又称其为开耳。

  2. 对于无向连通图 \(G\),若连通图序列 \((G_0,G_1,\dots G_d)\) 满足:

    • \(G_0\) 是一个简单环或者一个点

    • \(G_{i-1}\)\(G_i\) 的子图

    • \(G_i=(V_i,E_i)\),则 \(E_i-E_{i-1}\) 构成一个耳(开耳)

      则称 \((G_0,G_1\dots G_d)\) 为图 \(G\) 的耳分解(开耳分解)

定理

  1. 无向连通图 \(G\) 存在耳分解当且仅当 \(G\) 边双联通

    必要性:耳分解的流程中每个 \(G_i\) 都是边双联通的

    充分性:考虑 dfs 树,找到一条非树边 \(1\to x\),令这个与树上路径组成的环为 \(G_0\)

    假设现在已经生成了 \(G_i\),找到一个点 \(v\) 满足 \(v\notin V_i,u\in V_i\),若 \(V_i\neq V\) 必然可以找到,然后将 \(v\) 子树内选择一条跨出子树的返祖边加上 \(u\) 到返祖边端点的路径 作为一个耳生成 \(G_{i+1}\),由于边双连通不存在割点一定可以,至于最后多出来的非树边可以直接作为一个耳加入。

  2. 至少含有三个点的无自环无向连通图 \(G\) 存在开耳分解当且仅当 \(G\) 点双连通。

    证明是类似的,但是返祖边的另一个端点不能是 \(u\),根据点双连通性显然成立。

有向图版本

定义类似,有性质有向图可耳分解当且仅当强连通

这也告诉我们一个边双可以通过定向变为强连通

构造方法:

建立 \(dfs\) 树,父亲向子节点定向,返祖边后代向祖先定向即可。


混合图可以被定向为强连通图,当且仅当以下条件同时满足:

  1. 将有向边看作无向边,图边双连通
  2. 将无向边看作两条有向边后图强连通

我们断言,选出任意无向边,一定存在一种定向方式使得定向后本性质仍然满足。

条件一显然仍然满足,下面论证条件二。

设当前图为 \(G\),选出无向边 \((u,v)\),删掉它后图为 \(G_0\),那么由条件二可知 \(G_0\)\(u,v\) 至少是可达的,不妨设 \(u\) 可达 \(v\),如果此时 \(v\) 可达 \(u\) 显然成立。

否则,图至多最终分裂为两个强连通分量,因为只断掉一条边,因此对于每个其他点 \(x\),至少与 \(u,v\) 两者之一可达。

因此此时把边定向为 \(v\to u\) 就满足了。

双极定向

给定无向图 \(G=(V,E)\) 以及两个不同节点 \(s,t\),以下四个命题等价:

  1. 加入 \(s\to t\)\(G\) 点双连通
  2. \(G\) 的圆方树上所有方点都在一条链上
  3. 存在一种对 \(G\) 进行定向的方法使得得到一个 DAG,有且只有 \(s\) 没有入度,\(t\) 没有出度。
  4. 存在一个节点排列 \(p\)\(p_1=s,p_n=t\),满足任意前缀和任意后缀的导出子图都是连通的。

\(1,2\) 显然等价,\(3,4\) 是有向图与拓扑序的关系,也显然等价。

注意加入边 \(s\to t\) 后我们对图做开耳分解,根据可达性选择外部路径方向即可,这证明了 \(1\to 3\)

然后假设 \(4\) 成立,\(1\) 不成立,设一个割点 \(x\)(指加入边 \((s,t)\) 后,由于 \(1\) 不成立因此图不点双连通),在消去它后 \(s,t\) 处于同一连通块且 \(x\) 也处于一个连通块之中,取出这个连通块在 \(p\) 中第一个和最后一个出现的值,这两者之间至少一个不是 \(x\),那么根据前后缀连通又必须经过割点割点又不在则一定 \(4\) 不成立,矛盾。


实现方面:

考虑以 \(s\) 为根,求出每个节点的 \(low\),我们只需要保留这一条返祖边。

提出 \(t\to s\) 的链,然后建立新图 \(G'\),对于每个非链上的点,在新图中建立边 \(fa_u\to u,id[low_u]\to u\),然后按 \(s\to t\) 的顺序遍历链,遍历到一个点就开始深搜新图,并按照 dfs 序作为双极定向里的 \(p\) 即可。

按照 \(p\) 的顺序可以得出原图每条边的方向。

边三连通

建立无向图的 \(dfs\) 树(非树边都是返祖边),将所有非树边随机赋权,定义树边的权值覆盖其的非树边权值异或和(树上差分)

如果一个边集的 \(xor=0\),则说明是割集(充分条件)

dzy love Chinese

边三连通图定义为最小割集不小于 \(3\) 的连通无向图。

\(k\) 连通图性质:

  1. \(x,y\) 满足 \(k\) 连通则 \(y,x\) 满足
  2. \(x,y\)\(y,z\) 满足 \(k\) 连通则 \(x,z\) \(k\) 连通

考虑边权:

  1. 树边 \((u,v)\) 边权为零或者边权等于某条非树边,\(u\)\(v\) 及其子树内的点不边三连通
  2. 两条树边 \((u,v),(x,y)\) 边权相同,则必然为一条到根的链上的边,因此断掉这两条边后子树 \(v\) 减去子树 \(y\) 的部分被独立出去。

注意暴力删边是错误的

利用异或运算来简化判断。

对于情况 1,直接给子树 \(v\) 异或一个随机值。

对于情况 \(2\),直接给子树 \(v,y\) 异或上一个相同值。

可以通过打标记和再次 dfs 实现。

并且注意到,我们自底向上判断时,对于边权相同的树边只需要保留最浅的一条即可,画图易证。

模版:

双极定向:

int Dfn[N],Low[N],Idx,in[N],f[N],rew[N];
vector<int>Lik;
bool dfs(int u,int fa){
    Dfn[u]=Low[u]=++Idx;rew[Idx]=u;int tag=(u==Ed);
    for(auto v:ne[u])if(v!=fa){
        if(!Dfn[v])tag|=dfs(v,u),Low[u]=min(Low[u],Low[v]),in[u]++,f[v]=u;
        else Low[u]=min(Low[u],Dfn[v]);
    }
    if(tag)Lik.push_back(u);
    return tag;
}
int p[N],tot,dev[N];
vector<int>de[N];
void bianli(int x){
    if(dev[x])return ;
    dev[x]=1;
    p[++tot]=x;
    for(auto y:de[x])bianli(y);
}
void to_direct(){
    /*双极定向,还需要有一个遍历的在里面*/
    St=col[St],Ed=col[Ed];
    dfs(St,0);
    queue<int>q;
    for(int i=1;i<=node;++i)if(!in[i])q.push(i);
    while(!q.empty()){
        int u=q.front();q.pop();
        if(u==Ed)continue;
        /*
        shift,这里还需要注意到这条特别的链
        */
        de[f[u]].push_back(u);
        de[rew[Low[u]]].push_back(u);
        if(f[u]){
            --in[f[u]];
            if(!in[f[u]])q.push(f[u]);
        }
    }
    reverse(Lik.begin(),Lik.end());
    for(auto x:Lik)bianli(x);
}

边三连通

posted @ 2024-12-27 20:42  spdarkle  阅读(220)  评论(0)    收藏  举报