二分图最佳匹配

编程入门 行业动态 更新时间:2024-10-14 00:31:37

二分图最佳匹配

二分图最佳匹配

8616 汽车拉力比赛

时间限制:500MS  内存限制:1000K
提交次数:3 通过次数:3

题型: 编程题   语言: 无限制

描述

SCAU车队要去参加汽车拉力比赛啦。拉力比赛中,每辆汽车需要一个驾驶员和一个导航员。SCAU车队一共有有N个驾驶员和N个导航员,每个 驾驶员对每个导航员有一个默契值,现在需要求得某种N对N的配对,使得这N个配对的默契值之和最大。 

Input

多Case,每一个Case第一行是一个整数N,范围是(1<=N<=16)。接下来有N行,每行有N个数,第i行第j个数表示第i个驾驶员和第j个导航员的默契值。 测试数据会有多组,当N=0时表示数据结束,这行不用处理。

Output

输出配对后默契值之和的最大值。

Sample Input

1 5 2 10 20 25 5 0  

Sample Output

5 45  

Source

CPP 这题很明显的二分图最佳匹配,很显然我不会,果断去找资料,经过理解和研究标程,已经将其纳为己用了,这就是传说中的km算法,理解有点蛋疼,因为老说什么交错树,不知道是什么东东,不过不鸟它,看代码直接自己想能想通的,下面是我的代码。。。
#include<string>
#include<algorithm>
#define N 100
using namespace std;
int gp[N][N],vx[N],vy[N],fx[N],fy[N],n,m[N];
int dfs(int u)
{vx[u]=1;for(int i=0;i<n;i++){if(vy[i]==0&&fx[u]+fy[i]==gp[u][i]){vy[i]=1;if(m[i]==-1||dfs(m[i])){m[i]=u;return 1;}}}return 0;
}
int count()
{int i,j,k,d,ans;for(i=0;i<n;i++){fx[i]=-0x7fffffff;fy[i]=0;for(j=0;j<n;j++){if(fx[i]<gp[i][j]){fx[i]=gp[i][j];}}}memset(m,-1,sizeof(m));for(int u=0;u<n;u++){memset(vx,0,sizeof(vx));memset(vy,0,sizeof(vy));while(!dfs(u)){d=0x7fffffff;for(i=0;i<n;i++){if(vx[i])for(j=0;j<n;j++){if(!vy[j]){if(d>(fx[i]+fy[j]-gp[i][j]))d=fx[i]+fy[j]-gp[i][j];}}}for(i=0;i<n;i++){if(vx[i])fx[i]-=d,vx[i]=0;if(vy[i])fy[i]+=d,vy[i]=0;}}}ans=0;for(i=0;i<n;i++){ans+=gp[m[i]][i];}return ans;
}
int main()
{int i,j;while(1){scanf("%d",&n);if(n==0)return 0;for(i=0;i<n;i++)for(j=0;j<n;j++){scanf("%d",&gp[i][j]);}printf("%d\n",count());}return 0;
}


更多推荐

二分图最佳匹配

本文发布于:2024-02-25 19:17:36,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1700028.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!