二分图判定和割顶与桥的判断

二分图、割顶、桥都是图论中的重要知识点,很多题目在建模时都要用到。
因此二分图的判定算法和割顶与桥的判断算法都至关重要。
二分图的判定采用的是一个着色的方法,如果能将相邻的点涂上不同的颜色(颜色总数为2),那么这张图就是二分图了;

下面是相关代码:

int color[maxn];
vector<int>G[maxn];//邻接表

bool bipartite(int u)
{
    for(int i = 0 ; i < G[u].size() ; i++)
    {
        int v = G[u][i];
        if(color[u]==color[v])return false;
        if(!color[v])
        {
            color[v] = 3 - color[u];
            if(!bipartite(v))return false;
        }
    }
    return true;
}

割顶和桥的判断算法同样有重要的意义,它的思想在双连通分量和强连通分量的求解中得到应用(割顶是双连通分量的分割依据,因为双连通分量是无向图的极大子图,因此不同的双连通分量的公共的至多有一个,如果有就是割顶)。
对于一个图的dfs树,如果一个点A的子节点B及其子孙可以连回的最早的祖先P不比A早(即P=A或P的遍历在A之后)的话,那么这个点是割顶,同理如果B的子孙后代最早可以连回B的话,边(A,B)是图的桥;

下面是核心代码:

int low[maxn],pre[maxn],dfs_clock = 0;
vector<int>G[maxn];
bool iscut[maxn],isbridge[maxn][maxn];
int n,m;

int dfs(int u,int fa)
{
    int lowu = pre[u] = ++dfs_clock;
    int child = 0;
    for(int i = 0;i < G[u].size();i++)
    {
        int v = G[u][i];
        if(!pre[v])
        {
            child++;
            int lowv = dfs(v,u);
            lowu = min(lowu,lowv);
            if(lowu >= pre[u])
            {
                iscut[u] = true;
                if(lowu > pre[u])
                    isbridge[u][v] = true;
            }
        }
        else if(pre[v] < pre[u]&& v != fa)
            lowu = min(lowu,pre[v]);
    }
    if(fa < 0&&child==1)
        iscut[u] = false;
    low[u] = lowu;
    return lowu;
}

代码中可能有些判断显得冗余,但这样看起来思路更清晰。
其中用到的dfs_clock有一个好听的名字叫时间戳,是用来记录遍历顺序的。
之后博主会发一些关于上述代码的题解的,读者可以参考题目来理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值