ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

P3386 【模板】二分图最大匹配 题解(匈牙利算法)

2022-03-01 15:34:03  阅读:203  来源: 互联网

标签:尝试 vis int 题解 dfs P3386 模板 配对 match


题目连接

题目思路

如果不要去证明这个算法的正确性的话,我认为这只能算是一个简单贪心的dfs

可能一直被它高深的名字骗了没有去深入学习

时间复杂度\(O(nm)\) \(n\)代表点数,\(m\)代表边数

算法流程大概是如下 参考洛谷的题解

1.从任意一个没有被配对的点x开始,从点x的边中任意选一条边。如果此时点i没有被配对那么配对成功,则找到了一条增广路。如果点i此时已经被配对了,那么可以尝试将点match[i]与其他点配对。如果尝试成功,则找到一条增广路。这里用match[ ]来记录配对关系, 即match[i] = x。 并且将配对数+1。 这个过程我们用dfs来实现。

2.如果配对失败,就从点x的边中重选一条边尝试。直到点x配对成功或尝试完x所有的边。

3.接下来对没有配对的点一一进行配对,直到所有的点都尝试完毕找不到新的增广路。

二分图染色好像能解决一堆覆盖问题,以后有机会再好好了解下吧

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=5e2+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n,m,e;
vector<int> g[maxn];
bool vis[maxn];
int match[maxn];
bool dfs(int u){
    for(auto x:g[u]){
        if(vis[x]) continue;
        vis[x]=1;
        if(match[x]==-1||dfs(match[x])){
            match[x]=u;
            return 1;
        }
    }
    return 0;
}
signed main(){
   scanf("%d%d%d",&n,&m,&e);
   for(int i=1,u,v;i<=e;i++){
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
   }
   int ans=0;
   memset(match,-1,sizeof match);
   for(int i=1;i<=n;i++){
        memset(vis,0,sizeof vis);
        ans+=dfs(i);
   }
   printf("%d\n",ans);
    return 0;
}

标签:尝试,vis,int,题解,dfs,P3386,模板,配对,match
来源: https://www.cnblogs.com/hunxuewangzi/p/15950436.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有