二分图匹配是图论中的一个基础问题的。解决类似于找搭档的问题。有若干个人,每个人都有x个愿意搭档的人,问最后能否使得每个人都找到自己的搭档。如果一个人已经是别人的搭档了,那么他就不能是其他人的搭档。
二分图应该算是很经典的算法了吧。有比较固定的代码。
下面就记录一下二分图的部分代码,以备不时之需。
下面的vis数组标记该点有没有被询问过,ed数组表示两点是否有边相连,如果ed[x][y]=1 就表示x与y有边相连,即x愿意与y作为搭档,反之就是没有边相连;match数组表示与这个点相连的点是哪个。num1表示x的范围,num2表示y的范围。这边要注意的是:加入以男的出发寻找女的作为搭档,那么match数组的下标就代表女生的值。这些值都应该是全局变量。
int vis[1009],ed[1009][1009],match[1009];
int num1,num2;
这一部分是具体求解二分图的代码,我用了邻接矩阵存储图的相关信息。需要注意的是:这边的判断条件一定要写在更改标记之前,这边的顺序不能换。不然会出错T^T。
bool dfs(int num)
{
for(int i=0; i<num2; i++)
{
if(vis[i]==1||ed[num][i]==0)continue;
vis[i]=1;
if(match[i]==-1||dfs(match[i]))
{
match[i]=num;
return true;
}
}
return false;
}
下面的memset 初始化match数组,表示初始状态下所有的女生都没有被找为搭档
ans记录的是成功找到的搭档对数。
vis数组必须在每次寻找搭档的时候初始化。
memset(match,-1,sizeof(match));
int ans=0;
for(i=0; i<num1; i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))ans++;
}
下面的代码根据题目意思做相应的输出。
如果不是全部找到匹配,就做某某处理,否则即恰好能够组成一对一的搭档,就做某某处理
if(ans!=num1){
}
else {
}
以上就是二分图匹配的一些关键性代码。