poj3041二分图最优匹配
http://poj.org/problem?id=3041
本题我看了很长时间,但直到看了别人的解题思路才知道是二分图最优匹配o(╯□╰)o........
((((((转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1299322465
解题思路:把方阵看做一个特殊的二分图(以行列分别作为两个顶点集V1、V2,其中| V1|=| V2|)
然后把每行x或者每列y看成一个点,而障碍物(x,y)可以看做连接x和y的边。按照这种思路构图后。问题就转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。
再利用二分图最大匹配的König定理:
最小点覆盖数 = 最大匹配数 PS:最小点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖图的所有的边。
因此本题自然转化为求 二分图的最大匹配 问题))))))))
代码是我自己的。。。。。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int g[550][550]; int vis[550]; int dis[550]; int n,k; int match(int i) { for(int j=1;j<=n;j++) { if(vis[j]==-1&&g[i][j]==1) { vis[j]=1; if(dis[j]==-1||match(dis[j])==1) { dis[j]=i; return 1; } } } return 0; } int MMG() { int sum=0; memset(dis,-1,sizeof(dis)); for(int i=1;i<=n;i++) { memset(vis ,-1,sizeof(vis)); if(match(i))sum++; } return sum; } int main() { while(scanf("%d%d",&n,&k)!=EOF) { int x,y; for(int i=1;i<=k;i++) { scanf("%d%d",&x,&y); g[x][y]=1; } printf("%d\n",MMG()); } return 0; }

浙公网安备 33010602011771号