链接:https://ac.nowcoder.com/acm/contest/283/F
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
众所周知,在各种对抗类游戏里装备都是很重要的一环,不同的出装方案会给玩家带来不同的强度。
dalao手里有N件装备,现在dalao要把装备分给N个队友,每个队友只能分一件装备,而每个队友穿上不同的装备会有不同程度的强度提升。
现在给出每个队友对每件装备的强度提升的值,请问dalao的所有分配方案里,最多能让团队的总强度提升多少呢?
输入描述:
第一行有一个整数T,表示数据的组数(不会超过150组)
每组数据第一行包含一个整数N,接下来会有N行,每行有N个整数,其中第 a 行的第 b 个数字表示第 a 个队友穿上第 b 件装备的强度提升。任何队员穿任何装备的强度提升都不会超过20000。
输出描述:
对于每组数据在一行内输出一个整数表示强度能够提升的最大值
示例1
输入
2 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 3 1 3 5 2 4 6 7 9 11
输出
34 16
km算法模板题
ac:
#include<iostream>//slack:匹配 #include<algorithm>//match:松弛 #include<cstring>//gap:差距 #include<cstdio> #define inf 0x3f3f3f3f using namespace std; int n; int love[301][301]; int vis_girl[301],vis_boy[301]; int ex_girl[301],ex_boy[301]; int match[301],slack[301]; int dfs(int x) { vis_girl[x]=1; for(int i=0;i<n;i++) { if(vis_boy[i]) continue; int gap=ex_girl[x]+ex_boy[i]-love[x][i]; if(!gap){ vis_boy[i]=1; if(match[i]==-1||dfs(match[i])){ match[i]=x; return 1; } } else slack[i]=min(slack[i],gap); } return 0; } void km() { memset(match,-1,sizeof(match)); memset(ex_boy,0,sizeof(ex_boy)); for(int i=0;i<n;i++) { ex_girl[i]=love[i][0]; for(int j=1;j<n;j++) ex_girl[i]=max(ex_girl[i],love[i][j]); } for(int i=0;i<n;i++) { fill(slack,slack+n,inf); while(1){ memset(vis_boy,0,sizeof(vis_boy)); memset(vis_girl,0,sizeof(vis_girl)); if(dfs(i)) break; int d=inf; for(int j=0;j<n;j++) if(!vis_boy[j]) d=min(d,slack[j]); for(int j=0;j<n;j++){ if(vis_girl[j]) ex_girl[j]-=d; if(vis_boy[j]) ex_boy[j]+=d; else slack[j]-=d; } } } int res=0; for(int i=0;i<n;i++) res+=love[match[i]][i]; printf("%d\n",res); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&love[i][j]); km(); } return 0; }