什么叫二分图呢。。。

就是这样的。。。
通俗地讲 就是一个图有左右两部分 左右部分没有边 但是他们左右相连了
什么又叫匹配呢。。。比如就是这样一道题

现在你要使得情侣尽可能的多 这就叫二分图的匹配。。
匈牙利算法就是解决二分图匹配的经典算法
匈牙利算法其实就是一种网络流的思想 本质就是不断地寻找增广路,当找不到增广路的时候,当前增广路数量就是答案
定义数组:For 表示当前点已经匹配的点 used 标记数组 表示该点已经试图被查过了 如果查过(且used[i]=1 ) 就不必浪费功夫再查一遍(值得一提的是 used数组每次查询都要初始化为0)
查询过程:遍历左部分(右也行...)对于每一个点 从这个点出发,向它每一个相连的点遍历过去。如果这个点没有被查过,且这个点名花无主或者它的原本匹配点可以找到别人,那么就把这个点与出发点匹配
看代码吧(网络流24题第一题 飞行员配对方案问题)
//匈牙利算法的本质就是不断地寻找增广路,当找不到增广路的时候,当前增广路数量就是答案
#include<bits/stdc++.h>
using namespace std;
int tot,ans,m,n,x,y,used[505],For[505],first[505];
struct Edge
{
int next;
int to;
}edge[1000005];
inline void addedge(int x,int y)
{
edge[tot].to=y;
edge[tot].next=first[x];
first[x]=tot++;
}
inline void init()
{
memset(first,-1,sizeof(first));
for(int i=0;i<=1000004;i++) edge[i].next=-1;
}
bool find(int x)
{
for(int u=first[x];u!=-1;u=edge[u].next)
{
int vis=edge[u].to;
if(used[vis]==0) //如果没标记过
{
used[vis]=1;
if(find(For[vis])||For[vis]==0) //名花无主或者可以另寻他主
{
For[vis]=x;
return true;
}
}
}
return false;
}
int main()
{
// freopen("input.in","r",stdin);
cin>>m>>n;
init();
while(cin>>x>>y)
{
if(x==-1&&y==-1) break;
addedge(x,y);
}
for(int i=1;i<=m;i++)
{
memset(used,0,sizeof(used));
if(find(i)) ans++;
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)
{
if(For[i]!=0) cout<<For[i]<<" "<<i<<endl;
}
return 0;
}行了。。。就讲到这儿吧
本文探讨了二分图的概念,即图的左右两部分通过边相连但内部无边。二分图匹配问题,例如情侣配对,可以通过匈牙利算法来解决。匈牙利算法基于网络流思想,主要寻找增广路,当无法找到增广路时,当前匹配数即为最大匹配数。在实现过程中,使用For数组记录匹配状态,used数组标记已尝试节点,避免重复搜索。通过代码实例展示了匈牙利算法在飞行员配对方案问题的应用。
992

被折叠的 条评论
为什么被折叠?



