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

【总结】


《算法导论》笔记 第22章 总结与思考_第1张图片


【思考】


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];  
    vectorbcc[maxn];  
    stackstk;  
    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]


----


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 可达性




你可能感兴趣的:(算法导论)