再补一下

树上差分:

  点差分:路径u->v上加x

      w[u]+=x,w[v]+=x,w[LCA(u,v)]-= x ,w[fa[LCA(u,v)]]-=x

  边差分:同上: 

      w[u]+=x,w[v]+=x,w[LCA(u,v)]-=2*x

    关于粗体的部分,可以自己模拟一下

 

有关连通性:

  用途:随机图->缩点->DAG图->方便处理

  tarjan算法(yxc建议背模板)

  有向图强连通tarjan:

void tarjan(int u)
{
    low[u]=dfn[u]=++totn;
    sta[++tail]=u;
    instack[u]=1;
    for(int it=head[u];~it;it=nxt[it])
    {
        int to=e[it];
        if(dfn[to])
        {
            if(instack[to]) low[u]=min(low[u],low[to]);
        }
        else{
            tarjan(to);
            low[u]=min(low[u],low[to]);
        }
    }
    if(low[u]==dfn[u])
    {
        ids++;
        while(sta[tail]!=u)
        {
            siz[ids]++;
            int top=sta[tail];
            tail--;
            id[top]=ids;
            instack[top]=0;
        }
        int top=sta[tail];
        siz[ids]++;
        tail--;
        id[top]=ids;
        instack[top]=0;
    }
}

   无向图双连通:

 

void tarjan(int u,int from)
{
    low[u]=dfn[u]=++cnt;
    sta[++tail]=u;
    for(int it=head[u];~it;it=nxt[it])
    {
        int to=e[it];
        if(!dfn[to])
        {
            tarjan(to,it);
            low[u]=min(low[u],low[to]);
            if(dfn[u]<low[to])
            {
                is_bridge[it]=is_bridge[it^1]=1;
            }
        }
        else
        {
            if(it!=(from^1))
            {
                low[u]=min(low[u],dfn[to]);
            }
        }
    }
    if(dfn[u]==low[u])
    {
        int top;
        ids++;
        while(sta[tail]!=u)
        {
            top=sta[tail--];
            id[top]=ids;
        }
        top=sta[tail--];
        id[top]=ids;
    }
}

二分图:

  最小点覆盖点数=最大边匹配边数

  最大独立点集点数= 总点数 -最小点覆盖点数

  DAG最小路径点覆盖=二分图上:(二分图最大独立点集点数)

(证明太麻烦了,大概知道怎么回事就行)

欧拉回路、路径:

  无向图:回路:当所有点的度都为偶数时,从任一点出发,可以回到此点

      路径:存在回路,或者正好有2个点度数为奇数,从一个奇数点出发,回到另一个奇数点

  有向图:回路:当所有点入度=出度

      路径:存在回路,或者正好有一个点(入=出+1)并且正好有另一个点(出=入+1)

topsort:

  得到一个DAG的拓扑序,然后就可以按照顺序进行DP、递推,求解某值

posted @ 2023-06-05 20:05  ddt_cai  阅读(24)  评论(0)    收藏  举报