“东信杯”广西大学第一届程序设计竞赛(同步赛)-出装方案(km算法)

匿名 (未验证) 提交于 2019-12-02 23:03:14

链接: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; }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!