《算法导论》笔记 第22章 总结与思考

本文深入探讨了深度学习领域的关键算法,包括广度优先搜索在边分类的应用、挂接点和桥的概念解析,以及如何在O(E)时间内计算low[v]值。同时,文章还介绍了欧拉回路的深度优先搜索方法,通过实例展示了回路的发现过程。

【总结】




【思考】


22-1 通过广度优先搜索对边进行分类



22-2 挂接点、桥以及双连通分支

a) G_π的根是G的挂接点,当且仅当在G_π中该根顶点至少有两个子女。


b) 设v是G_π中的某一非根顶点,证明v是G的挂接点当且仅当v有一个子顶点s,使得不存在从s或s的任何后裔顶点指向v的某个真祖先顶点的反向边。


c) 设low[v]=min(d[v],d[w]),d[w]:对v的后裔u,(u,w)是反向边

试说明对所有顶点v∈V,如何在O(E)时间内计算出low[v]。


----

资料:https://www.byvoid.com/blog/biconnect

----


const int maxn=1111;  
const int maxm=5111;  
int n,m;  
  
struct EDGENODE{  
    int to;  
    int w;  
    bool cut;  
    int next;  
};  
struct SEDGE{  
    int u;  
    int v;  
    SEDGE(int uu=0,int vv=0){u=uu;v=vv;}  
};  
struct BCC_GRAPH{  
    int head[maxn];  
    EDGENODE edges[maxm];  
    int edge;  
    void init()  
    {  
        clr(head,-1);  
        edge=0;  
    }  
    void addedge(int u,int v,int c=0)  
    {  
        edges[edge].cut=0,edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;  
    }  
    //BCC_Tarjan  
    int dfn[maxn],low[maxn],bccno[maxn],dfs_clock,bcc_cnt;  
    bool iscut[maxn];  
    vector<int>bcc[maxn];  
    stack<SEDGE>stk;  
    int dfs(int u,int fa)  
    {  
        int lowu=dfn[u]=++dfs_clock;  
        int child=0;  
        for (int i=head[u];i!=-1;i=edges[i].next)  
        {  
            int v=edges[i].to;  
            if (v==fa) continue;  
            SEDGE e=SEDGE(u,v);  
            if (!dfn[v])  
            {  
                stk.push(e);  
                child++;  
                int lowv=dfs(v,u);  
                lowu=min(lowu,lowv);  
                if (dfn[u]<=lowv) //cut 割点  
                {  
                    iscut[u]=true;  
                    //done 点双连通  
                    bcc_cnt++;  
                    bcc[bcc_cnt].clear();  
                    SEDGE x;  
                    do{  
                        x=stk.top();  
                        stk.pop();  
                        if (bccno[x.u]!=bcc_cnt)  
                        {  
                            bcc[bcc_cnt].push_back(x.u);  
                            bccno[x.u]=bcc_cnt;  
                        }  
                        if (bccno[x.v]!=bcc_cnt)  
                        {  
                            bcc[bcc_cnt].push_back(x.v);  
                            bccno[x.v]=bcc_cnt;  
                        }  
                    }while (x.u!=u||x.v!=v);  
                    //over  
                }  
                if (dfn[u]<lowv)  //cut 桥  
                {  
                    edges[i].cut=true;  
                    edges[i^1].cut=true;  
                }  
            }  
            else if (dfn[v]<dfn[u])  
            {  
                stk.push(e);//done  
                lowu=min(lowu,dfn[v]);  
            }  
        }  
        if (fa<0&&child==1) iscut[u]=0;  
        low[u]=lowu;  
        return lowu;  
    }  
    void find_bcc(int n)  
    {  
        while (!stk.empty()) stk.pop();  
        clr(dfn,0);  
        clr(iscut,0);  
        clr(bccno,0);  
        dfs_clock=bcc_cnt=0;  
        REP_1(i,n)  
        {  
            if (!dfn[i]) dfs(i,-1);  
        }  
    }  
    //another  
    int block[maxn];  
    int vis[maxn];  
    int b_num;  
    void b_dfs(int u)  
    {  
        vis[u]=true;  
        block[u]=b_num;  
        for (int i=head[u];i!=-1;i=edges[i].next)  
        {  
            if (edges[i].cut) continue;  
            int v=edges[i].to;  
            if (!vis[v]) b_dfs(v);  
        }  
    }  
    void find_block(int n)  
    {  
        //find_block 边双连通  
        clr(block,0);  
        clr(vis,0);  
        b_num=0;  
        REP_1(i,n)  
        {  
            if (!vis[i])  
            {  
                b_num++;  
                b_dfs(i);  
            }  
        }  
    }  
}solver;  


----


22-3 欧拉回路

使用深度优先搜索,如果某条边被搜索到,则标记这条边为已选择,并且即使回溯也不能将当前边的状态改回未选择,每次回溯时,记录回溯路径。深度优先搜索结束后,记录的回溯路径就是欧拉回路。

----

void dfs(int u)  
{  
    for (int i=1;i<=n;i++)  
    {  
        if (a[u][i])  
        {  
            a[u][i]=false;  
            a[i][u]=false;  
            dfs(i);  
            ans[++cnt]=i;  
        }  
    }  
}  


----


22-4 可达性




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值