【KM算法】HDU2255-奔小康赚大钱
2016-04-04 15:59
429 查看
KM算法的裸体。O(n^4)的模板,实际上在增广路径的时候依然有冗余,可以用bfs优化到O(n^3)。
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int MAXN=400+5; const int INF=0x7fffffff; int n,m; int w[MAXN][MAXN]; int x[MAXN],y[MAXN]; int visx[MAXN],visy[MAXN],slack[MAXN]; int lk[MAXN]; int dfs(int u) { visx[u]=1; for (int i=1;i<=n;i++) { int wt=x[u]+y[i]-w[u][i]; if (!visy[i] && wt==0) { visy[i]=1; if (lk[i]==-1 || dfs(lk[i])) { lk[i]=u; return 1; } } else if (slack[i]>wt) slack[i]=wt; } return 0; } int KM() { memset(lk,-1,sizeof(lk)); for (int i=1;i<=n;i++) { y[i]=0; x[i]=-INF; for (int j=1;j<=n;j++) x[i]=max(x[i],w[i][j]); } for (int i=1;i<=n;i++) { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); memset(slack,127,sizeof(slack)); while (!dfs(i)) { int delta=INF; for (int j=1;j<=n;j++) if (!visy[j] && slack[j]<delta) delta=slack[j]; for (int j=1;j<=n;j++) { if (visx[j]) { x[j]-=delta; visx[j]=0; } if (visy[j]) { y[j]+=delta; visy[j]=0; } } } } int ret=0; for (int i=1;i<=n;i++) ret+=x[i]+y[i]; return ret; } void init() { memset(w,0,sizeof(w)); for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) scanf("%d",&w[i][j]); } } int main() { while (~scanf("%d",&n)) { init(); printf("%d\n",KM()); } return 0; }
相关文章推荐
- Memcached启动参数
- 我的编程之路——知识管理与知识体系
- Distributing Ballot Boxes(HDU1490)
- linux进程基础
- hibernate4 映射集合属性 bag
- Oracle 11g系统自己主动收集统计信息的一些知识
- POJ 2010 Moo University - Financial Aid
- Android ContentObserver
- 腾讯笔试题
- 逻辑数据库设计 - 单纯的树(递归关系数据)
- HYSBZ 2653 middle(二分+主席树)
- 231. Power of Two
- JS中使用JQuery
- [Android 插件化(一)] DynamicLoadApk的用法
- ActiveRecord之Oracle中文乱码
- intellij idea包依赖 ivy 和ant结合使用
- leetcode_094 Binary Tree Inorder Travelsal
- C++类
- Codeforces Round #346 (Div. 2)D. Bicycle Race
- FTP应答码