二分图

二分图的判定(染色法)

int col[Z];
bool dfs(int rt, int color)
{
    col[rt] = color;
    for (int i = head[rt]; i; i = e[i].ne)
    {
        int son = e[i].v;
        if (!col[son] && !dfs(son, 3 - color)) return false;//子节点集合中有冲突 
        if (col[son] == color) return false;//一条边相连的两个节点属于同一个二分集合 
    }
    return true;
}
inline bool judge()
{
    for (int i = 1; i <= n; ++i)
        if (!col[i] && !dfs(i, 1)) return false;
    return true;
}

匹配:任意两条边都没有公共顶点。

点覆盖:图中任意一条边都有至少一个端点属于该集合。

独立集:任意两点之间都没有边相连。

团:任意两点之间都有一条边相连。

由某些定理得:二分图的最小点覆盖的点数 = 最大匹配的边数;

二分图的最大独立集的大小 = \(n\) - 最小点覆盖数(最大匹配数)。

匈牙利算法(增广路):求二分图的最大匹配,当且仅当图中不存在增广路。

bool vs[Z];
int match[Z];
bool dfs(int rt)
{
    for (int i = head[rt]; i; i = e[i].ne)
    {
        int son = e[i].v;
        if (!vs[son])
        {
            vs[son] = 1;
            if (!match[son] || dfs(match[son]))
            {
                match[son] = rt;//目标点还未匹配 或 目标点能与原匹配点脱离 
                return true;
            }
        }
    }
    return false;
}
sandom main()
{
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        memset(vs, 0, sizeof(vs));
        if (dfs(i)) ++ans;
    }
    return 0;
}

多重匹配:拆点,类似于背包问题。

带权匹配:\(KM\)算法

posted @ 2022-04-25 15:13  sandom  阅读(29)  评论(0编辑  收藏  举报