二分图匹配实例代码及整理

二分图匹配实例代码及整理

1、匈牙利算法

HDU 1150

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int m,n,k;
int vis[105];
int mpt[105][105];
int use[105];
int hungary(int x)
{
  for(int i=1;i<m;i++)
  {
    if(vis[i]==0&&mpt[x][i]==1)
    {
      vis[i]=1;
      if(use[i]==-1||hungary(use[i]))
      {
        use[i]=x;
        return 1;
      }
    }
  }
  return 0;
}
int main()
{
  while(scanf("%d",&n)!=EOF,n)
  {
    scanf("%d%d",&m,&k);
    int a,b,c;
    memset(mpt,0,sizeof(mpt));
    for(int i=1;i<=k;i++)
    {
      scanf("%d%d%d",&c,&a,&b);
      mpt[a][b]=1;
    }
    int ans=0;
    memset(use,-1,sizeof(use));
    for(int i=1;i<n;i++)
    {
      if(hungary(i))
      {
        ans++;
      }
      memset(vis,0,sizeof(vis));
    }
    printf("%d\n",ans);
  }
  return 0;
}

2、KM算法

HDU 2255

看了很多资料都还不是很懂、、先贴别人的模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
using namespace std;
#define N 310
int map[N][N];
bool visitx[N], visity[N];
int lx[N], ly[N];
int match[N];
int n; 

bool Hungary(int u) //匈牙利算法
{
  visitx[u] = true;
  for(int i = 0; i < n; ++i)
  {
    if(!visity[i] && lx[u] + ly[i] == map[u][i])
    {
      visity[i] = true;
      if(match[i] == -1 || Hungary(match[i]))
      {
        match[i] = u;
        return true;
      }
    }
  }
  return false;
} 

void KM_perfect_match()
{
  int temp;
  memset(lx, 0, sizeof(lx)); //初始化顶标
  memset(ly, 0, sizeof(ly)); //ly[i]为0
  for(int i = 0; i < n; ++i) //lx[i]为权值最大的边
    for(int j = 0; j < n; ++j)
      lx[i] = max(lx[i], map[i][j]);
  for(int i = 0; i < n; ++i) //对n个点匹配
  {
    while(1)
    {
      memset(visitx, false, sizeof(visitx));
      memset(visity, false, sizeof(visity));
      if(Hungary(i)) //匹配成功
        break;
      else //匹配失败,找最小值
      {
        temp = INT_MAX;
        for(int j = 0; j < n; ++j) //x在交错树中
          if(visitx[j])
            for(int k = 0; k < n; ++k) //y在交错树外
              if(!visity[k] && temp > lx[j] + ly[k] - map[j][k])
                temp = lx[j] + ly[k] - map[j][k];
        for(int j = 0; j < n; ++j) //更新顶标
        {
          if(visitx[j])
            lx[j] -= temp;
          if(visity[j])
            ly[j] += temp;
        }
      }
    }
  }
} 

int main()
{
  int ans;
  while(scanf("%d", &n) != EOF)
  {
    ans = 0;
    memset(match, -1, sizeof(match));
    for(int i = 0; i < n; ++i)
      for(int j = 0; j < n; ++j)
        scanf("%d", &map[i][j]);
    KM_perfect_match();
    for(int i = 0; i < n; ++i) //权值相加
      ans += map[match[i]][i];
    printf("%d\n", ans);
  }
  return 0;
}

3、多重匹配

HDU  3605 Escape

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int num[15];
int mpt[100005][15];
int vis[15];
int use[15];
int dp[15][100005];
int hungary(int x)
{
  for(int i=1;i<=m;i++)
  {
    if(vis[i]==0&&mpt[x][i]==1)
    {
      vis[i]=1;
      if(use[i]<num[i])//满足条件
      {
        dp[i][use[i]++]=x;
        return 1;
      }
      //不满足则寻找增广路
      for(int j=0;j<use[i];j++)//看能否回溯一个出去
      {
        if(hungary(dp[i][j]))
        {
          dp[i][j]=x;
          return 1;
        }
      }
    }
  }
  return 0;
}
int main()
{
  while(scanf("%d%d",&n,&m)!=EOF)
  {
    for(int i=1;i<=n;i++)
    {
      for(int j=1;j<=m;j++)
      {
        scanf("%d",&mpt[i][j]);
      }
    }
    for(int i=1;i<=m;i++)
      scanf("%d",&num[i]);
    int ans=0;
    memset(use,0,sizeof(use));
    for(int i=1;i<=n;i++)
    {
      memset(vis,0,sizeof(vis));
      if(!hungary(i))
      {
        ans=1;
        break;
      }
    }
    if(ans==0)
    {
      printf("YES\n");
    }
    else printf("NO\n");
  } 

  return 0;
}

以上就是二分图匹配的实现代码,如有疑问请留言,或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 二分图匹配实例代码及整理

    二分图匹配实例代码及整理 1.匈牙利算法 HDU 1150 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int m,n,k; int vis[105]; int mpt[105][105]; int use[105]; int hungary(int x) { for(int i=1;i<m;i++) { if(vis[i]==0&&mp

  • C++ string 字符串查找匹配实例代码

    在写C++程序中,总会遇到要从一个字符串中查找一小段子字符串的情况,对于在C中,我们经常用到strstr()或者strchr()这两种方法.而对于C++的string,我们往往会用到find(). C++:#inlcude<string> C: #include<string.h> find():在一个字符串中查找一个指定的单个字符或字符数组.如果找到,就返回首次匹配的开始位置:如果没有查找到匹配的内容,就返回string::npos. find_first_of():在一个目标串

  • 正则表达式匹配(URL、电话、手机、邮箱)的实例代码

    正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表通常被用来检索.替换那些符合某个模式(规则)的文本.下面通过实例代码给大家介绍正则表达式匹配(URL.电话.手机.邮箱)的实例代码,一起看看吧! 废话不多说了,直接给大家贴代码了,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta ch

  • Java使用正则表达式(regex)匹配中文实例代码

    只能输入中文 /** * 22.验证汉字 * 表达式 ^[\u4e00-\u9fa5]{0,}$ * 描述 只能汉字 * 匹配的例子 清清月儿 */ @Test public void a1() { Scanner sc = new Scanner(System.in); String input = sc.nextLine(); String regex = "^[\\u4e00-\\u9fa5]*$"; Matcher m = Pattern.compile(regex).matc

  • MyBatis创建存储过程的实例代码_动力节点Java学院整理

    所需要用到的其他工具或技术: 项目管理工具 : Maven 测试运行工具 : Junit 数据库 : Derby 本节需要用到的有2部分,第一部分是如何在Derby中创建存储过程,第二部分是如何在Mybatis中调用存储过程 一. 在Derby中创建存储过程 在Eclipse中创建一个新的普通Java项目命名为Test_Store_Procedure 在com.bjpowernode.practice包下创建一个Class命名为StoreProcedureOperationClass.class

  • PHP正则匹配日期和时间(时间戳转换)的实例代码

    先来一个比较简单实用的代码 日期YYYY-MM-DD $str = ''; $isMatched = preg_match('/^\d{4}(\-|\/|.)\d{1,2}\1\d{1,2}$/', $str, $matches); var_dump($isMatched, $matches); php需要一定的时间格式才能转换成时间戳(表示从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数),这就要用到php正则判断,以下是代码: <?php //匹配时间格式为2016-0

  • PHP用正则匹配form表单中所有元素的类型和属性值实例代码

    前言 最近工作中遇到一个需求,需要在正则匹配页面中,所有可能存在的 form 表单的元素,可能有 input,action,select,textarea等等所有可能的元素,本文给出一个代码示例.感兴趣的朋友们可以参考学习. 实例代码如下 假设页面 1.html 的网页源代码是: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>一个含有 form 表单

  • Android 手势 正则匹配图片实例代码

    为没有手势的控件(ViewFlipper) 添加手势 xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools

  • 实例代码详解正则表达式匹配换行

    在javascript中,使用正则表达式匹配换行可能会遇到各种问题,下面就通过实例介绍一下如何实现此功能. <div id="main"> <div id="left"> </div> <div id="right"> 我们 </div> </div> 如果DIV内没有内容则不换行 把上面的改为: <div id="main"> <div

  • python正则表达式匹配IP代码实例

    这篇文章主要介绍了python正则表达式匹配IP代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 import re re.search(r'([1]\d\d|2[0-4]\d|25[0-5])','192') #re.search(r'([01]\d\d)','1XX') #[01] \d \d # 1 0-9 0-9 #re.search(r'(2[0-4]\d)','2XX') #2 [0-4] \d #2 0-4 0-9 #re.

随机推荐