素数伴侣 匈牙利算法
来源:互联网 发布:淘宝双11红包攻略活动 编辑:程序博客网 时间:2024/06/10 07:33
对于0和1来说,它们既不是素数也不是合数。
任何一个大于1的正整数n,可以且唯一表示成有限个素数的乘积。
素数:在一个大于1的自然数中,除了1和此整数自身以外,不能被其他自然数整除的数。
比1大,但不是素数则称之为合数。
匈牙利算法:https://liam0205.me/2016/04/03/Hungarian-algorithm-in-the-maximum-matching-problem-of-bigraph/
增广路径的理解:
理解一:在二分图的匹配中,如果一条路径的首尾是非匹配点,路径中除此之外(如果有)其他的点均是匹配点,那么这条路径就是一条增广路径(Agumenting path)。
理解二:
交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。
增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。
增广路径的首尾是非匹配点。因此,增广路径的第一条和最后一条边,必然是非匹配边;同时它的第二条边(如果有)和倒数第二条边(如果有),必然是匹配边;以及第三条边(如果有)和倒数第三条边(如果有),一定是非匹配边。
亦即,增广路径从非匹配边开始,匹配边和非匹配边依次交替,最后由非匹配边结束。这样一来,增广路径中非匹配边的数目会比匹配边大 1。
1.定义:若无向图G=<V,E>的结点集V能够被划分为两个子集V1,V2,满足V1∩V2=Ø,并且V1UV2=V,使得G中任意一条边的两个端点,一个属于V1,另一个属于V2,则称G为二分图(bigraph)。二分图通常记为G=<V1,E,V2>.
由定义可知,二分图没有自回路;零图,平凡图可以看成是特殊的二分图。
2.定义:在二分图G=<V1,E,V2>中,若V1中的每个结点与V2中的每个结点都有且仅有一条边相关联,则称二分图G为完全二分图,记为Ki,j,其中i=|V1|,j=|V2|.
3.判断是否为二分图的方法:①定义法,②定理:无向图G=<V,E>为二分图的充要条件是G的所有回路的长度均为偶数。
4.在二分图G=<V1,E,V2>中,V1={v1,v2,v3........vq},若存在E的子集E'={(v1,v1'),(v2,v2')........(vq,vq'),其中v1',v2',v3'.......vq'为V2中的q个不同的结点},则称G的子图G'={V1,E',V2}为从V1到V2的一个完全匹配(complete matching)。(需要注意的是,这里对于v2来说并不一定格式一个完全匹配,因为v2中可能不只q个节点!!!)
5.二分图存在完全匹配的判断:
①充要条件-------霍尔定理(Hall定理):二分图G=<V1,E,V2>中存在从V1到V2的匹配的充要条件是V1中任意k个结点至少与V2中的k个结点相邻,k=1,2,3,........|V1|. 通常称为相异性条件(diversity condition)
②充分不必要条件---------定理(t条件):二分图G=<V1,E,V2>如果满足:
(1)V1中每个结点至少关联t条边;
(2)V2中每个结点之多关联t条边。
其中t为正整数,则G存在从V1到V2的匹配。
判断t条件非常简单,只需计算V1中结点的最小度,V2中结点的最大度即可。
③必要条件---------|V1|<=|V2|
无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。
二部图中两个集合中的节点数量可以不相同!!!
饱和点和匹配:
给定给一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M为一个匹配。
极大匹配是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。
最大匹配是所有极大匹配中边数最大的一个匹配。
如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。
若图中顶点vi与M中的边相关联,则称vi是M饱和点,否则称为非饱和点。
Hall定理:http://www.cnblogs.com/zxfx100/archive/2012/07/26/2609704.html这篇文章对Hall定理以及证明有很详细的讲解!!!
匈牙利算法可以用深度遍历以及广度遍历来实现:
https://my.oschina.net/husthang/blog/840806
https://www.byvoid.com/zhs/blog/hungaryZ这是大神写的,里面对匈牙利算法用画图的方式进行了生动的解析,非常好,可以关注一下!!参考这个博客以及word里面的
程序可以很好的理解匈牙利算法!!!
#include <iostream>
#include <vector>
#include <string.h>
#include <stdio.h>
using namespace std;
bool isPrime(int x){//判断x是否为质数
if(x<2)
return false;
if(x==2)
return true;
for(int i=2;i<x;i++){
if(x%i==0)
return false;
}
return true;
}
bool dfs(int k,int* match,int** adj,int* visited,vector<int>& even){//length代表是even的长度
int t;
int temp;
int length=even.size();
for(int i=0;i<length;i++){
temp=even[i];
if(adj[k][temp]==1&&visited[i]==0){
visited[i]=1;
t=match[i];
match[i]=k;
if(t==-1||dfs(t,match,adj,visited,even))
return true;
match[i]=t;
}
}
return false;
}//dfs函数只对匹配过的odd中的点有影响,如果之前odd中的s是没有被匹配过的,那么
//执行完这次的dfs之后也不会对s产生任何影响,它也不会变成匹配过的点
int main(){
int N;
cin>>N;//输入自然数个数
while(N%2!=0){
cin>>N;//保证输入的N为偶数
}
int* number=new int[N];
for(int i=0;i<N;i++){
cin>>number[i];
}
//先创建邻接表,相加为素数则邻接表中的值为1
int** adj=new int*[N];
for(int r=0;r<N;r++){
adj[r]=new int[N];
}
int temp;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
temp=number[i]+number[j];
if(isPrime(temp)&&(i!=j))
adj[i][j]=1;//adj中的下标对应number中的下标
else
adj[i][j]=0;
}
}
//将number中的数据分成奇数和偶数
vector<int> odd;//奇数
vector<int> even;//偶数
for(int k=0;k<N;k++){
if(number[k]%2==0)
even.push_back(k);//这里面放的是number下标
else
odd.push_back(k);//这里面放的是number下标
}
// 初始化数组visited,表示even中的点i是否被访问过
int length=even.size();
int* visited=new int[length];
for(int jj=0;jj<length;jj++){
visited[jj]=0;
}
//初始化数组match,表示数组even中的点i的匹配点,初始化为-1
int* match=new int[length];
for(int kk=0;kk<length;kk++){
match[kk]=-1;
}
//下面是对odd和even中的点进行最大匹配算法
int sum=odd.size();
int count1=0;
for(int p=0;p<sum;p++){
memset(visited,0,sizeof(int)*length);//这里一定要将visited清零
if(dfs(odd[p],match,adj,visited,even)){
count1=count1+1;
}
}
cout<<count1<<"\n";
//注意这里不可以用final作为变量名,这样的话是无法cout的!!
delete number;
for(int t=0;t<N;t++){
delete[] adj[t];
}
delete[] adj;
delete[] visited;
delete[] match;
return 0;
}
上面的程序实现用到了一个重要性质就是:素数,除了2是偶数,其他是奇数。并且,2个数的和是奇数的情况只有奇数+偶数。
饱和
- 素数伴侣 匈牙利算法
- 华为oj之素数伴侣---匈牙利算法
- 华为OJ之素数伴侣-匈牙利算法
- OJ中-----素数伴侣(二分图,匈牙利算法)*?
- 华为oj素数伴侣,利用匈牙利算法求解
- 牛客网 素数伴侣(二分图最大匹配,匈牙利算法)
- 匈牙利算法 素数间隔
- 素数伴侣
- 素数伴侣
- 素数伴侣
- 华为OJ_2129_素数伴侣
- 素数伴侣-动态规划
- 素数伴侣-动态规划
- 华为oj素数伴侣
- 华为素数伴侣题目
- 华为OJ(素数伴侣)
- 【华为OJ】【074-素数伴侣】
- 华为机试---素数伴侣
- Codevs 2382 挂缀
- laravel groupby 分组
- ERLANG 安装及环境变量配置
- Nginx之日志管理
- 命令行操作mysql
- 素数伴侣 匈牙利算法
- Linux bash 管道符及多命令执行
- POJ 1035 Spell checker
- 如何实现mybatis+Springboot 关联查询
- linux 安装mysql
- win7 MySQL5.7.18 免安装版 安装教程
- STM32库函数USART_SendData的缺陷和解决方法
- 离开---梦想不变
- 排序算法---之插入排序(直接插入排序&希尔排序)