二分图 (匈牙利算法)

二分图的匈牙利算法

二分图的难点主要在建图;

关于二分图的几个重要公式:

    最大匹配数=最小点覆盖

    最小边覆盖=顶点总数-最大匹配数/2 (这个要拆点:uN=vN=cnt,ans=cnt-hungary/2)

    最大团=补图最大独立集

    最大独立集=顶点数-最大匹配

匈牙利算法:

  顶点编号 u= 1~uN,v=uN+1~uN+vN,加边的时候加u到v的单向边就可以了,因此建图前要将原图分为u和v两个子图。

int link[maxn];
vector<int>G [maxn];
int uN,vN;
bool vis[maxn];

bool dfs(int u)
{
    for(int i=0;i<G[u].size();i++){  //取出u的下一个未访问过的点v
        int v=G[u][i];
        if(!vis[v]){
            vis[v]=1;
            if(link[v]==-1||dfs(link[v])){  //如果link[v]==-1或dfs(link[v]),反转:link[v]=u;
                link[v]=u;
                return true;
            }
        }
    }
    return false;
}

int hungary()
{
    int res=0;
    memset(link,-1,sizeof(link));  //初始化link数组
    for(int u=1;u<=uN;u++){
        memset(vis,0,sizeof(vis));  //注意每次需初始化vis数组
        if(dfs(u)) res++;
    }
    return res;
}
hungary算法

采用vector代替邻接矩阵模拟邻接表,提高效率又不增加代码量

 

转载于:https://www.cnblogs.com/--560/p/4330134.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值