C
来源:互联网 发布:淘宝一千零一夜视频4 编辑:程序博客网 时间:2024/05/16 15:41
匈牙利算法
本文采自:http://blog.csdn.net/lyy289065406/article/details/6646007
题目描述:你的飞船有个强大的武器可以打小行星,一次可以攻击一行或者一列,求最少的攻击次数。
题目分析:问题可以转化为,选取最少的点,使得这些点与所有的边相邻。把方阵看做一个二分图,v1作为行顶点集,v2作为列顶点集,那x,y可以看做点,图中的点graph[x][y]则可以看做一条边,问题就是最小点覆盖数问题=最大匹配数,用匈牙利算法。
代码如下:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int maxn=500+10;int v1,v2;int graph[maxn][maxn];//构建的图int visit[maxn];//v2的点是否访问过int girl[maxn];//v1所匹配的y;bool dfs(int x){ for(int i=1;i<=v2;i++) { if(graph[x][i]&&!visit[i]) { visit[i]=1; if(girl[i]==0||dfs(girl[i])) { girl[i]=x; return true; } } } return false;}void solve(){ memset(girl,0,sizeof(girl)); int cnt=0; for(int i=1;i<=v1;i++) { memset(visit,0,sizeof(visit));//清空上次搜索的标记 if(dfs(i)) cnt++; } cout << cnt << endl;}int main(){ int n,m; scanf("%d %d",&n,&m); v1=v2=n; memset(graph,0,sizeof(graph)); for(int i=0;i<m;i++) { int x,y; scanf("%d %d",&x,&y); graph[x][y]=1; } solve(); return 0;}
初学匈牙利算法,大体明白怎么回事了,以后追加新的理解。
推荐一个博文:http://blog.csdn.net/dark_scope/article/details/8880547
阅读全文
0 0