您的位置:首页 > 其它

二分图最大匹配算法-匈牙利算法

2016-07-18 09:21 169 查看
二分图:把一个图G(V,E)的顶点集V划分为两个不相交顶点集 V1和 V2,且V=V1UV2,使得每一条边的顶点分别在V1 、V2  中。

未盖点:设u是图G的一个顶点,如果存在一条匹配边与u相关联,就称u是一个覆盖点,如果不存在这样的匹配边,则u就是一个未覆盖点。

交错路:设路径P是图G的一条路,如果P的任意两条相邻的边一定是一条属于M而另一条不属于M,就称P是一条交错路。

可增广路:两个端点都是未盖点的交错路叫做可增广路。 

下面给出基于深度搜索的完美匹配算法-匈牙利算法:

#include<iostream>
#include<cstring>
using namespace std;
bool graph[100][100];
int visit[100],flag[100];
int n1,n2,m;
bool dfs(int x)
{
for(int i=1; i<=n2; i++)
{
if(graph[x][i]&&!visit[i])         //节点x与i之间存在边,且i不在增广路中
{
visit[i]=1;                   //把i加入增广路;
if(flag[i]==0||dfs(flag[i]))  //i是未盖点 或者 从i的对应项出发有可增广路
{
flag[i]=x;                //修改i的对应项为x;
return true;              //则从x的对应项出有可增广路
}
}
}
return false;                         //则从x的对应项出没有可增广路
}
int main()
{
cin>>n1>>n2>>m;
memset(graph,0,sizeof(graph));
for(int i=1; i<=m; i++)               //矩阵表示二部图
{
int x,y;
cin>>x>>y;
graph[x][y]=1;
}
memset(flag,0,sizeof(flag));
int count=0;
for(int i=1; i<=n1; i++)
{
memset(visit,0,sizeof(visit));
if(dfs(i))count++;
}
cout<<"最大匹配边数:"<<count<<endl;
cout<<"匹配边:"<<endl;
for(int i=1;i<=n2;i++)
if(flag[i]>0)
cout<<"("<<flag[i]<<","<<i<<")"<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: