二分图匹配,江湖称二分匹配,图论相关算法。
现在给出两个集合,我们拿约会来举例子。一方是男生集合,一方是女生集合,女生都比较内敛,对不认识的男孩纸并不喜欢一起约会,所以这里边就要有人际关系的问题了。
这里给男生编号n1,n2.....nn;女生编号v1v2....vn;
下面给出女生认识的男生的列表:
v1 :n1 ,n2.
v2 :n2, n3.
v3 : n1.
这里显而易见,1号男生2号男生是比较受欢迎的哈~。不用算法思想的去想这个问题我们可以这样思考:三号女生只认识1号男生,匹配上。(1组搞定)这个时候一号女生就不能选择1号男生了,她只能去选2号男生,这时候2号女生也就有了自己能选择的男生,这里我们就匹配成功了:
v1 n2
v2 n3
v3 n1
这里我们就完成了匹配的过程,这个时候我们因为所有人都有了约会对象,我们这个时候称之为最大匹配,同时也是完美匹配。
最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。刚刚给出的例子就是完美匹配。
从v1开始找,先找到了n1.约上,然后是v2,找到了n2,约上。v3找到了n1,但是这里n1和v1已经约好了,怎么办呢?v1对v3说:我还认识n2,我去问问他有没有约会人选,要是没有的话,n1让给你。(其实我想说她是傻逼。。。。)然后v1去找n2,但是n2和v2约上了,这个时候呢v2对v1说:我还认识n3,我去看看他有没有约会的人选,要是没有的话n2,让给你(这两个傻逼。。。。)然后v2找到了n3,n3乐的屁颠屁颠的,说正好没人约我,然后他俩约上了,v2找到了n3,那么v1就能和v2约上了,然后v3也就能和n1约上了,我们这个时候就从刚刚的两组匹配,转到了3组匹配。
刚刚所述的过程,其实就是在找增广路。(这里增广路的含义自己就可以理解了吧~)那么我们如何用代码实现这个过程呢?其实并不难,我们这里需要三个数组,一个是图,一个是询问vis标记,一个是match匹配。
int map[n][n];//关系图。//这里我们用1表示有关系0表示没有关系 int vis[n];//表示是否询问过这个人 用1表示询问过 0表示没有询问过 int match[n];//数组内数据表示匹配关系:比如match[1]=2表示男1和女2约上了(不一定最后也是在一起的)然后就是寻找的过程:
int find(int x)//这里x表示是任何一个女生 { for(int i=0;i<n;i++)//这里的i表示男生 { if(vis[i]==0&&map[x][i]==1)//如果这个男生没有询问过(你总不能一直问一个人吧....本来就够逗逼了,你还要缠着人家。。。)并且你和这个男生认识(要找到自己认识的男生啊~) { vis[i]=1;//标记询问过了 if(match[i]==-1||find(match[i]))//如果当前女孩纸是来直接找约会对象的,或者是要抛弃当前男孩去找下一个男孩的(而且找到了)。 { match[i]=x;//当前男生和女生约上了(i男x女) return 1;//返回找到了~~~ } } } return 0; }
杭电2063
6 3 3 1 1 1 2 1 3 2 1 2 3 3 1 0
3
#include<stdio.h> #include<string.h> using namespace std; const int maxn = 505; int map[maxn][maxn]; //记录是否可以匹配,0表示不能,1表示能 int vis[maxn]; //用在不同队伍匹配是的标记作用 int pri[maxn]; int k,m,n; int find(int x) { for(int i=1;i<=m;i++) { if(vis[i]==0&&map[i][x]) { vis[i]=1; if(pri[i]==-1||find(pri[i])) { pri[i]=x; return 1; } } } return 0; } int main() { while(~scanf("%d",&k)) { if(k==0)break; scanf ("%d%d", &m, &n); memset (map, 0, sizeof (map)); memset (pri, -1, sizeof (pri)); for(int i=0;i<k;i++) { int a,b; scanf("%d%d",&a,&b); map[a][b]=1; } int output=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(find(i)) output++; } printf("%d\n",output); } }