http://acm.hdu.edu.cn/showproblem.php?pid=2063
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5243 Accepted Submission(s): 2320
#include <stdio.h> #include <string.h> #define max 510 int match[max][max]; int link[max]; bool used[max]; int k,n,m; bool dfs(int u) //深搜遍历,寻找增广路径 { for(int v=1;v<=n;v++) { if(match[u][v]&&!used[v]) { used[v]=true; if(link[v]==-1||dfs(link[v])) { link[v]=u; return true; } } } return false ; } int Xiong() { int res=0; memset(link,-1,sizeof(link)); for(int i=1;i<=m;i++) { memset(used,false,sizeof(used)); if(dfs(i)) res++; //找到增广路径则匹配树加1 } return res; } int main() { int x,y; while(scanf("%d",&k)==1&&k) { memset(match,0,sizeof(match)); // 这里WA 了一次.. SB了 .... scanf("%d%d",&m,&n); for(int i=1;i<=k;i++) { scanf("%d%d",&x,&y); match[x][y]=1; } printf("%d\n",Xiong()); } return 0; }
匈牙利算法:(求偶图的最大匹配 注:偶图就是不存在奇数圈的连通图) 首先要明白几个概念:
二分图:设G=(V,E)是一个无向图,顶点集可以分割为两个互不相交的子集,并且图中每条边依附的顶点 都属于不同的子集,只有偶图有二分图,奇图没有;
匹配:在G的一个子图M中,M的边集都不依附于同余同一顶点,这样的图中边数最多的图称为图的最大匹配; 如果一个匹配中,包括图中所有的顶点,则称为此匹配为完全匹配,也叫完备匹配;
增广路的定义(也叫增广轨或者交错轨这个是匹配中一个最重要的概念) 如果P是图G中一条连通P是图G中一条连通两个未匹配顶点(起点和终点不在已匹配图中)的路径, 并且属M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。
由增广路的定义可以推出下述三个结论:
1-P的路径长度必定为奇数,第一条边和最后一条边都不属于M,既起点和终点不在已匹配图中。
2-P经过取反操作可以得到一个更大的匹配M’,(取反:原来在匹配中的边变成不在匹配中,不在的变成在每一次);
3-M为G的最大匹配当且仅当不存在相对于M的增广路径, 用增广路求最大匹配(称作匈牙利算法,匈牙利数学家Edmonds于1965年提出)
算法轮廓: (1)置M为空
(2)找出一条增广路径P,通过取反操作获得更大的匹配M’代替M
(3)重复(2)操作直到找不出增广路径为止
时间复杂度 邻接矩阵:最坏为O(n^3) 邻接表:O(nm)
空间复杂度 O(n^2) O(m+n) 模板:
int dfs(int i)
{
int j;
for(j = 0;j<n; j++)
{
if(g[i][j]&&!mark[j]) //注意: g[i][j]放前面执行效率要高些因为g[i][j]为假比mark[j]=1次数多很多
{
mark[j] = 1;
if(link[j]==-1||dfs(link[j])) //link[j]==-1已找到了一条增广路,不等找其后继结点;
{
link[j] = i; //记录后继结点;
return 1;
}
}
}
return 0; //没找到返回0;
}
int main()
{
int i,sum = 0;
memset(link,-1,sizeof(link)); //初始化后继结点;
for(i = 0; i<n; i++)
{
memset(mark,0,sizeof(mark)); //重新标记未访问;
if(dfs(i))
sum++; //找到一条新的增广路加一;
}
}
匈牙利算法可以解决的图的问题:
(二分图) 1.图的最小点覆盖数 = 图的最大匹配数;
2.图的最大点独立集 = 图顶点数 - 图的最大匹配数;
3.图的最小路径覆盖数 = 原图的顶点数 - 原图拆点后形成的二部图的最大匹配数;
题目推荐:pku2446 pku2594 pku1325 pku1469