HDU 2853 Assignment & HDU 3315 My Brute
来源:互联网 发布:淘宝网中华活胰宝 编辑:程序博客网 时间:2024/05/16 06:04
两道的题型都是:给出现有的匹配,让你求匹配的权值最大时,改动的边数。
方法就是把边上标记,上标记的方法就是把权值扩大比N大的一个倍数,比如说N:50,那么我们就扩大55倍,原来已经存在的匹配边权值再加1,就这样,无论有原有匹的匹配边有多少条,一定要小于55,通过这样又标记出了没有改变的匹配边。求得ans/55时,这个值就是最大的匹配权值,ans%55就是没有改变的匹配边。
/*HDU 2853*/#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <map>#include <cctype>using namespace std;const int maxn = 60;const int INF = 0x3f3f3f3f;int n, m;int W[maxn][maxn];int Lx[maxn], Ly[maxn];int Left[maxn];bool S[maxn], T[maxn];bool match(int i){ S[i] = 1; for(int j = 1; j <= m; j++) if(Lx[i]+Ly[j] == W[i][j] && !T[j]) { T[j] = 1; if(!Left[j] || match(Left[j])) { Left[j] = i; return 1; } } return 0;}void update(){ int a = INF; for(int i = 1; i <= n; i++) if(S[i]) for(int j = 1; j <= m; j++) if(!T[j]) a = min(a, Lx[i]+Ly[j]-W[i][j]); for(int i = 1; i <= n; i++) { if(S[i]) Lx[i] -= a; } for(int j = 1; j <= m; j++) { if(T[j]) Ly[j] += a; }}void KM(){ memset(Left, 0, sizeof(Left)); memset(Lx, 0, sizeof(Lx)); memset(Ly, 0, sizeof(Ly)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) Lx[i] = max(Lx[i], W[i][j]); } for(int i = 1; i <= n; i++) { for(;;) { for(int j = 1; j <= m; j++) S[j] = T[j] = 0; if(match(i)) break; else update(); } }}inline void readint(int &x){ char c; c = getchar(); while(!isdigit(c)) c = getchar(); x = 0; while(isdigit(c)) x = x*10+c-'0', c = getchar();}inline void writeint(int x){ if(x > 9) writeint(x/10); putchar(x%10+'0');}int N, M;int sum;void read_case(){n = N, m = M;for(int i = 1; i <= N; i++)for(int j = 1; j <= M; j++){readint(W[i][j]);W[i][j] *= 100;}sum = 0;for(int i = 1; i <= N; i++){int x; readint(x);sum += W[i][x];W[i][x] += 1;}}void solve(){read_case();KM();int ans = 0;for(int i = 1; i <= m; i++) if(Left[i]) ans += W[Left[i]][i];int ans1 = N-ans%100, ans2 = ans/100 - sum/100;writeint(ans1), putchar(' '), writeint(ans2), puts("");}int main(){while(~scanf("%d%d", &N, &M)){solve();}return 0;}
/*HDU 3315*/#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <map>#include <cctype>using namespace std;const int maxn = 100;const int INF = 0x3f3f3f3f;int n, m;int W[maxn][maxn];int Lx[maxn], Ly[maxn];int Left[maxn];bool S[maxn], T[maxn];bool match(int i){ S[i] = 1; for(int j = 1; j <= m; j++) if(Lx[i]+Ly[j] == W[i][j] && !T[j]) { T[j] = 1; if(!Left[j] || match(Left[j])) { Left[j] = i; return 1; } } return 0;}void update(){ int a = INF; for(int i = 1; i <= n; i++) if(S[i]) for(int j = 1; j <= m; j++) if(!T[j]) a = min(a, Lx[i]+Ly[j]-W[i][j]); for(int i = 1; i <= n; i++) { if(S[i]) Lx[i] -= a; } for(int j = 1; j <= m; j++) { if(T[j]) Ly[j] += a; }}void KM(){ memset(Left, 0, sizeof(Left)); memset(Lx, 0, sizeof(Lx)); memset(Ly, 0, sizeof(Ly)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) Lx[i] = max(Lx[i], W[i][j]); } for(int i = 1; i <= n; i++) { for(;;) { for(int j = 1; j <= m; j++) S[j] = T[j] = 0; if(match(i)) break; else update(); } }}inline void readint(int &x){ char c; c = getchar(); while(!isdigit(c)) c = getchar(); x = 0; while(isdigit(c)) x = x*10+c-'0', c = getchar();}inline void writeint(int x){ if(x > 9) writeint(x/10); putchar(x%10+'0');}int N;int V[maxn];int H[maxn], P[maxn];int A[maxn], B[maxn];int check(int i, int j){int Hi = H[i], Pi = P[j];int d1 = A[i], d2 = B[j];for(;;){Pi -= d1;if(Pi <= 0) return 1;Hi -= d2;if(Hi <= 0) return 0;}return -1;}void read_case(){n = m = N;for(int i = 1; i <= N; i++) readint(V[i]);for(int i = 1; i <= N; i++) readint(H[i]);for(int i = 1; i <= N; i++) readint(P[i]);for(int i = 1; i <= N; i++) readint(A[i]);for(int i = 1; i <= N; i++) readint(B[i]);}void build(){for(int i = 1; i <= N; i++)for(int j = 1; j <= N; j++){if(check(i, j) > 0){W[i][j] = V[i]*100;}else{W[i][j] = -V[i]*100;}if(i == j) W[i][j] += 1;}}void solve(){read_case();build();KM();int ans = 0;for(int i = 1; i <= m; i++) if(Left[i]) ans += W[Left[i]][i];if(ans > 0){int ans1 = ans/100;double ans2 = 1.0*(ans%100)/N * 100;printf("%d %.3lf%%\n", ans1, ans2);}else { printf("Oh, I lose my dear seaco!\n"); return ; }}int main(){while(~scanf("%d", &N) && N){solve();}return 0;}
- HDU 2853 Assignment & HDU 3315 My Brute
- HDU 3315 My Brute(费用流)
- HDU 3315 My Brute(费用流)
- HDU 3315 My Brute 费用流
- hdu 3315 My Brute 网络流
- HDU 3315 My Brute KM算法
- HDU 3315 My Brute(费用流)
- HDU 3315 My Brute(KM算法)
- HDU 3315 My Brute(KM最大匹配)
- HDU 3315 My Brute(二分图最优匹配)
- HDU 2853 Assignment KM
- hdu 2853 — Assignment
- HDU 3315 My Brute 费用流+求错位率(好题)
- HDU 3315 My Brute(二分图最优匹配:优先用原匹配边)
- hdu 3315 My Brute 费用流,费用最小且代价最小
- My Brute (hdu 3315 二分图最大权匹配KM算法)
- HDU 3315 My Brute(二分图最优匹配:优先用原匹配边)
- HDU 3316 My Brute(二维费用流)经典
- 解决Ubuntu下N卡双显卡切换问题
- hdu 4616 经典树形dp 多校第二场
- uva10498 Happiness
- MySQL 备份和恢复策略(二)
- CUDA最佳实践(二)
- HDU 2853 Assignment & HDU 3315 My Brute
- MySQL 备份和恢复策略(三)
- hdu1402 傅里叶变换
- 关于赛车游戏制作的一点体会
- [poj 1182]食物链[并查集][图解+注释]
- Java学习之道:hibernate二级缓存的实现
- 淘宝天猫店铺微信公众平台建设指南
- UVAlive 5869 Airport 解题报告
- QT 实现QLabel上的超链接