博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu1150 Machine Schedule (匈牙利算法模版)
阅读量:4577 次
发布时间:2019-06-08

本文共 2108 字,大约阅读时间需要 7 分钟。

匈牙利算法本质就是一个个的匹配,对于当前的处理的对象i,假设他的匹配对象为j,但是j已经和v匹配好了,那么就让v去找找着能不能和别人匹配

v可以和别人匹配则i与j匹配,不能则i去找别人匹配

另外引入几个定义和结论:

1:最大匹配数 + 最大独立集 = n + m(n,m为二分图两边的节点数)

2:二分图的最小顶点覆盖数 = 最大匹配数

3:最小路径覆盖 = 最大独立集

最大独立集是指:求一个二分图中最大的一个点集,该点集内的点互不相连。

最小顶点覆盖是指: 在二分图中,用最少的点,让所有的边至少和一个点有关联。

最小路径覆盖是指:

对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。

 

最大匹配是指:

对于二分图的所有边,寻找一个子集,这个子集满足两个条件,

1:任意两条边都不依赖于同一个点。
2:让这个子集里的边在满足条件一的情况下尽量多。

 算法的证明如下:http://blog.csdn.net/yuxue_23/article/details/12224067

然后是模版:

bool find(int x){    int i,j;    for (j=1;j<=m;j++){    //扫描每个妹子        if (line[x][j]==true && used[j]==false)              //如果有暧昧并且还没有标记过(这里标记的意思是这次查找曾试图改变过该妹子的归属问题,但是没有成功,所以就不用瞎费工夫了)        {            used[j]=1;            if (girl[j]==0 || find(girl[j])) {                 //名花无主或者能腾出个位置来,这里使用递归                girl[j]=x;                return true;            }        }    }    return false;}int main(){for (i=1;i<=n;i++){    memset(used,0,sizeof(used));    //这个在每一步中清空    if find(i) all+=1;}  return 0;       }

然后是本题代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;#define PF(x) cout << "debug: " << x << " ";#define EL cout << endl;#define PC(x) puts(x);typedef long long ll;#define CLR(x, v) sizeof (x, v, sizeof(x))using namespace std;const int INF = 0x5f5f5f5f;const int N= 1000050;const int maxn=110;int n,m,k,used[maxn],lk[maxn][maxn],mark[maxn];bool find(int u){ for(int i = 1;i <= m;i++){ if(lk[u][i]&&!used[i]){ used[i] = 1; if(mark[i] == 0||find(mark[i])){ mark[i] = u; return true; } } } return false;}int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ if(n == 0) break; memset(lk,0,sizeof(lk)); memset(mark,0,sizeof(mark)); scanf("%d%d",&m,&k); int i,a,b,c; for(i = 1;i <= k;i++){ scanf("%d%d%d",&c,&a,&b); lk[a][b] = 1; } int ans=0; for(i = 1;i <= n;i++){ memset(used,0,sizeof(used)); if(find(i)) ans++; } cout<
<

 

转载于:https://www.cnblogs.com/shimu/p/5799350.html

你可能感兴趣的文章
Asp.Net webconfig中使用configSections的用法
查看>>
mysql 二进制日志
查看>>
阻止putty变成inactive
查看>>
TP框架代码学习 学习记录 3.2.3
查看>>
doc文档生成带目录的pdf文件方法
查看>>
js数组,在遍历中删除元素(用 for (var i in arr)是无效的 )
查看>>
通过前端上传图片等文件的方法
查看>>
在 OC 中调用 Swift 代码
查看>>
安卓|五大逆向软件下载
查看>>
5 OK6410裸机调试(不用Jlink)
查看>>
“模板”学习笔记(5)-----编译器在处理函数模板的时候都干了啥
查看>>
教你用shell写CGI程序
查看>>
窗口 对话框 Pop Dialog 示例
查看>>
ubuntu(centos) server安装vmware tools
查看>>
数据结构之最大不重复串
查看>>
为什么要配置sdk-tools/platform-toools?
查看>>
自己动手开发更好用的markdown编辑器-07(扩展语法)
查看>>
队列的循环队列
查看>>
程序中的日期格式
查看>>
大众点评CAT错误总结以及解决思路
查看>>