HDU 3315 KM My Brute
2015-09-11 20:29
253 查看
参考题解
二分图的最优匹配。图很容易建立。再处理相似度的时候。把每个权值扩大100倍。然后再对i==j时 特殊标记。使他们的权值再++1。后面选择的时候就很容易挑出。按原匹配
匹配的个数。 100*(double)(res%100)/n。即可得到第二问。
代码君
二分图的最优匹配。图很容易建立。再处理相似度的时候。把每个权值扩大100倍。然后再对i==j时 特殊标记。使他们的权值再++1。后面选择的时候就很容易挑出。按原匹配
匹配的个数。 100*(double)(res%100)/n。即可得到第二问。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn = 100; const int INF = 0x3f3f3f3f; int n; int V[maxn], H[maxn], P[maxn], A[maxn], B[maxn]; // KM algorithm int W[maxn][maxn], lft[maxn]; int slack[maxn]; int Lx[maxn], Ly[maxn]; bool S[maxn], T[maxn]; int inline divide(int a, int b) { int ans = a / b; if(a % b) ans++; return ans; } bool match(int u) { S[u] = true; for(int v = 1; v <= n; v++) if(!T[v]) { int t = Lx[u] + Ly[v] - W[u][v]; if(t == 0) { T[v] = true; if(!lft[v] || match(lft[v])) { lft[v] = u; return true; } } else slack[v] = min(slack[v], t); } return false; } void update() { int a = INF; for(int i = 1; i <= n; i++) if(!T[i]) a = min(a, slack[i]); for(int i = 1; i <= n; i++) { if(S[i]) Lx[i] -= a; if(T[i]) Ly[i] += a; else slack[i] -= a; } } void KM() { memset(Ly, 0, sizeof(Ly)); memset(lft, 0, sizeof(lft)); for(int i = 1; i <= n; i++) Lx[i] = -INF; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) Lx[i] = max(Lx[i], W[i][j]); for(int i = 1; i <= n; i++) { memset(slack, 0x3f, sizeof(slack)); for(;;) { memset(S, false, sizeof(S)); memset(T, false, sizeof(T)); if(match(i)) break; update(); } } } int main() { while(scanf("%d", &n) == 1 && n) { for(int i = 1; i <= n; i++) scanf("%d", V + i); for(int i = 1; i <= n; i++) scanf("%d", H + i); for(int i = 1; i <= n; i++) scanf("%d", P + i); for(int i = 1; i <= n; i++) scanf("%d", A + i); for(int i = 1; i <= n; i++) scanf("%d", B + i); //build graph for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { int score = V[i] * 100; int round1 = divide(P[j], A[i]); int round2 = divide(H[i], B[j]); if(round1 > round2) score = -score; if(i == j) score++; W[i][j] = score; } KM(); int ans = 0; for(int i = 1; i <= n; i++) ans += W[lft[i]][i]; if(ans < 0) { puts("Oh, I lose my dear seaco!"); continue; } printf("%d ", ans / 100); printf("%.3f%%\n", 100.0 * (ans % 100) / n); } return 0; }
代码君
相关文章推荐
- TCP/IP、Http、Socket的区别
- POJ 1157 LITTLE SHOP OF FLOWERS (插画的最大值_经典的动态规划DP)
- 图像匹配之归一化积相关灰度匹配
- Ubuntu设置代理和例外
- 基于飞思卡尔i.MX 6Quad Sabrelite开发板的触摸屏调试
- Machine Intelligence(Nature Insight 2015.5.28/Vol 521/Issue No 7553)
- 单例模式及单例类的两种实现
- img标签src路径不变,读取不同图片时,图片不刷新甚至不显示
- 4_蒙特卡罗算法求圆周率PI
- 4_蒙特卡罗算法求圆周率PI
- 【Java多线程】-线程同步synchronized和volatile
- 学习如何学习
- hdu2433
- hdu2222Keywords Search AC自动机模板题
- ubuntu14.04 搭建java环境
- ZooKeeper集群配置
- 木头打大孔的新方法-燃烧法
- Processing 练习(10) - 条形码
- 新的征程
- yum ftp源搭建