poj 3041二分匹配
2013-12-14 20:01
363 查看
题意:矩阵上有一些小行星,占据了一些格子,我们每次操作可以清理一列中的所有小行星,也可以清理一行中的所有小行星,问最少进行多少次操作可以清理掉所有的小行星。
分析:建图之后,会发现,题目意思就等于:最小覆盖点,
最小覆盖点 = 最大匹配;
问题就 = 求二分图的最大匹配数。
对于匈牙利算法有两种形式:
1、bfs 时间32ms
//32ms
2、dfs 时间 16ms
本来两种形式算法的效率的差不多的,但在这个题目中相差一倍,可能是测试数据的原因。
分析:建图之后,会发现,题目意思就等于:最小覆盖点,
最小覆盖点 = 最大匹配;
问题就 = 求二分图的最大匹配数。
对于匈牙利算法有两种形式:
1、bfs 时间32ms
//32ms
#include #include using namespace std; const int MAXN = 520; int g[MAXN][MAXN], Mx[MAXN], My[MAXN], Nx,Ny; int chk[MAXN], Q[MAXN], prev[MAXN]; int MaxMatch(void) { int res = 0; int qs, qe; memset(Mx, -1, sizeof(Mx)); memset(My, -1, sizeof(My)); memset(chk, -1, sizeof(chk)); for (int i = 1; i <= Nx; i++) { if (Mx[i] == -1) {//对于x集合中的每个没有匹配的点i进行一次bfs找交错轨 qs = qe = 0; Q[qe++] = i; prev[i] = -1; bool flag = 0;//判断是否找到 while (qs < qe && !flag) { int u = Q[qs]; for (int v = 1; v <= Nx && !flag; v++) if (g[u][v]//如果u和v相连 &&chk[v] != i)//并且v没有被u check过 { chk[v] = i; Q[qe++] = My[v];//放进 if (My[v] >= 0)//如果v和其他的相连,则修改之 prev[My[v]] = u; else {//直到找到一个u和v都没有用过的 flag = 1; int d = u, e = v; while (d != -1) {//确保回到最初 int t = Mx[d]; Mx[d] = e; My[e] = d; d = prev[d]; e = t; } } } qs++; } if (Mx[i] != -1) res++; } } return res; } int main() { cin>>Nx>>Ny; memset(g , 0 ,sizeof(g)); int i , x , y; for(i = 1 ; i <= Ny ;i++) { scanf("%d%d" , &x , &y); g[x][y] = 1; } int sum = MaxMatch(); cout<<sum<<endl; return 0; }
2、dfs 时间 16ms
#include #include using namespace std; const int MAX = 520 ; int grap[MAX][MAX] , link[MAX] , useif[MAX] ; int n , m; int can(int t) { int i; for(i = 1 ; i <= n ; i++) { if(grap[t][i] &&!useif[i]) { useif[i] =1; if(link[i] ==-1 || can(link[i])) { link[i]= t; return1; } } } return 0; } int main() { scanf("%d %d" , &n , &m); int i , x , y; memset(grap , 0 , sizeof(grap)); for(i = 1 ; i <= m ; i++) { scanf("%d %d" , &x ,&y); grap[x][y] = 1; } memset(link , -1 , sizeof(link)); int sum = 0; for(i = 1 ; i <= n ; i++) { memset(useif , 0 ,sizeof(useif)); if(can(i)) sum +=1; } printf("%d\n" , sum); return 0; } //16ms
本来两种形式算法的效率的差不多的,但在这个题目中相差一倍,可能是测试数据的原因。
相关文章推荐
- scanf和cin的区别 (效率的差距)
- 匈牙利算法
- poj 1062 最短路
- poj 1860 最短路
- poj 3259 最短路(带负环)
- poj 3080
- poj 1035
- poj 2965
- 欢迎您在新浪博客安家
- UnsupportedOperationException
- 黑马程序员—GUI(键盘事件)小例子
- 嵌入式学习之路(十)——C语言学习(5)
- U盘装win7 “安装程序无法创建新的系统分区,也无法定位现有的系统分区“最终解决方法
- 14.java NumberFormat 类
- 给iOS开发新手送点福利,简述UITextField的属性和用法
- 13.java MessageFormat 类
- 黑马程序员—GUI(菜单)小例子
- S3C6410+WinCE+GPIO+流驱动+详细过程
- 项目视频讲解_360问答系统
- Centos yum 错误