二分图匹配-Hopcroft-Karp

O(V^ 0.5 * m)
(对匈牙利的优化,比匈牙利算法略快)

原理:在增广匹配集合M时,每次同时寻找多条不相交的增广路径。

反正我没看懂是什么鬼,记下模板再说
int map[nx][ny];
int xlink[nx],ylink[ny];   // xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。
int dx[nx], dy[ny];   // dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号
int dis;
bool visit[ny];   //寻找增广路的标记数组

bool bfs(){
    queue<int> q;   // 存左集合的点
    dis=INF;
    memset(dx,-1,sizeof(dx));
    memset(dy,-1,sizeof(dy));
    for(int i=1;i<=nx;i++)
        if(xlink[i]==-1){
            q.push(i);   // 所有没被匹配的x入队
            dx[i]=0;
        }
    while(!q.empty()){
        int p=q.front();
        q.pop();
        if(dx[p]>dis)break;
        for(int v=1;v<=ny;v++)
            if(map[p][v]&&dy[v]==-1){
                dy[v]=dx[p]+1;
                if(ylink[v]==-1)
                    dis=dy[v];
                else{
                    dx[ylink[v]]=dy[v]+1;
                    q.push(ylink[v]);
                }
            }
    }
    return dis!=INF;
}

bool dfs(int p){
    for(int v=1;v<=ny;v++)
        if(map[p][v]&&!vis[v]&&dy[v]==dx[p]+1){
            vis[v]=true;
            if(ylink[v]!=-1&&dy[v]==dis)continue;
            if(ylink[v]==-1|| dfs(ylink[v])){
                xlink[p]=v;
                ylink[v]=p;
                return true;
            }
        }
    return false;
}

int Max_match(){
    memset(xlink,-1,sizeof(xlink));
    memset(ylink,-1,sizeof(ylink));
    int ans=0;
    while(bfs()){
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=nx;i++)
            if(xlink[i]==-1&&dfs(i))
                ans++;
    }
    return ans;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值