P1559 运动员最佳匹配问题

 洛谷——P1559 运动员最佳匹配问题

叹气向还是最终之心腹。—题记

问题叙述

羽毛球队有男性阴运动员各n人。给一定2
单n×n矩阵P和Q。P[i][j]举凡男性运动员i和女性运动员j配对成混合双打的男运动员竞赛优势;Q[i][j]是女性运动员i和男运动员j配合的阴运动员比试优势。由于技术兼容与思想状态相当各种因素影响,P[i][j]切莫肯定当Q[j][i]。男运动员i和女性运动员j配对组合混合双打的男女双方竞赛优势也P[i][j]*Q[j][i]。设计一个算法,计算男女选手最佳配对法,使各组男女双方竞赛优势的总数达到至极深。

1

日本奈良的清晨,小林俊介又起习的迷梦中惊醒,梦里是海滨邑的暮色,海市蜃楼的景点撩人。那种给皮筋勒住手指的觉得还在稳稳地镇住他的神经,使他安静—像奈良的清早。小林俊介不觉得清晨时有发生差不多安宁,光线刺眼,风吹过都像于侵犯。

早餐吃得异常少,小林俊介没有食欲,窗外白鸽的翎翅震耳欲聋,在他看来只是单调的振幅。上班之地铁上因满了沙丁鱼一般的人群,三分之一背在对肩膀背包,三分之一通过白色尼龙袜子。还有的三分之一丢掉在人流里就再也为查找不至了。大家沉默地并免去坐,不吵闹,脸上不悲不喜。小林俊介这时候最放松,他酷爱这种严寒的痛感,他尽管如相同块纯棉的白布,被尖的刀口绞着剪着,这种冷,尤其要他振奋。工作其间的单人隔间紧紧连却互不相干,大家自愿地涵养这无异种秩序—可能并死也是。小林俊介没想过非常,没想了音乐,女人愈加深恶痛绝,她们捉摸不定,疑神疑鬼,自卑多情。小林俊介的同上过去了。

输入输出格式

输入格式:

首先执有1 个刚整数n
(1≤n≤20)。接下来的2n行,每行n个数。前n行是p,后n行是q。

输出格式:

用计产生的男女双方竞赛优势葡京注册赠送88的总数的尽老价值输出。

2

初中生小林俊介很贴近本分,因为起小家教严格。学校是同等所全封闭式的过夜学校,小林俊介身材精瘦,时常成为欺凌的靶子。班上发出了号称捣蛋的“橙色兄弟”总好用他取乐,最沉痛的均等软是自从丢半单耳垂。即使挨了自,“橙色兄弟”受到教导处警告,小林俊介的心已罩下了恐怖与不安的米,这吃他想到了平时于夫人吃的辱骂。父母不在家吗从未关心他的郁闷,自卑得找不交朋友,那些日子,小林俊介总是梦见自己给绑,折磨,醒矣不畏趁着在夜间大家睡着的时刻溜出去看清冷的月光。小林俊介孤影相伴,就当平安夜前夕,同学等吵吵嚷嚷三复半夜才了睡去,节日的繁华让小林俊介尤为郁结,月色下的教室一片狼藉。打闹后的断壁残垣:礼花,喷雾剂,散落的礼物盒,纸袋还有少的衣,桌子椅子横七竖八,

黑板上叫砸了一致深团食用黄油,粘在一个女儿领结,阴性的,不定式的。小林俊介看正在教室,突然地,窗户外一律一味小鸟的身形一闪,是夜莺吗?小林俊介记得4载时以太太的地下室找到同样按照旧旧的【安徒生童话】,说夜莺是碰头唱歌的飞禽,可以拉动福灵。眼前的鸟类低飞正,然后抱于课桌上,倒了下,这是均等才受伤的禽,右腿有疤痕。小林俊介绞了平等段子纱布把受伤的地方钻好,找来一个盒子,一边想象夜莺唱歌一边将其藏起来。绝不会落入他手。在拿包扎好伤口的禽放入盒子的等同寺院那,月光下那只鸟的眼神,神圣清净,旁边摆在蜡烛,像是吃安全夜送上之第一篇赞歌。

小林俊介有一段时间没做梦了,每天看在鸟儿康复使他坦然,甚至快,连“橙色兄弟”也未克影响至外。这只是鸟成了他的心腹,一将钥匙,给了他答案。他看出一样栽鸟类羽毛特别油亮,是拉不停止的,而及时就是是那就上帝之夜莺。一个晚小林俊介睡得特别不安,这老怪。他翻身起来,径直走至那鸟的躲藏的所。走及一半,月光依然,淅淅沥沥拍起在窗户上,远远地扩散不谐和的嬉闹声,是“橙色兄弟”,几单玩世不恭的男孩子不知从哪打来蜡烛,像电视里那样围成一个缠点燃,那无非夜莺就在当中。夜莺!小林俊介踢碎窗户玻璃冲过去,冲着她们同拳,“橙色兄弟”见老大被由一卷蜂把他论到,蜡烛灭了一半,剩余的烛光中,那无非夜莺惨不忍睹,小林俊介的血迹混杂在雪一般的毛,粘在粘贴于本地的面颊,他深受打伤了,夜莺死了,暗淡无光。小林俊介的悲愤涌了上去,他挣脱箍住的招,朝着小腹一阵猛踹,倒了一个,另一个而来接招。小林俊介一直于由,不顾死活,后来重新为尚未来学校。

3

下班晚底小林俊介没有觉得今日发出什么两样,走及地铁,一个带来在鸭舌帽看不清脸面的汉子因为于外身边,突然伸出拿空玻璃啤酒瓶的手发出其奇怪的来了转…

小林俊介站在明晃晃日光下,之前发生了什么一无所知,也非晓怎么就来临了这里,这个中教室。崭新一片,没有丁。小林俊介呆呆的,这即是颇曾今给他带动了平静,抚慰了他的音为?窗外阳光滚滚,小林俊介很喜悦,那无非夜莺变成了太阳鸟,羽毛如烟花,它重,生了,小林俊介觉得温暖的,昏昏得沉睡了…

地铁及的小林俊介睁开眼睛,错过好几站了,身边的隐秘男人以读报,似笑不笑地扣押了他一致眼,到站下车了。小林俊介惊叹此人的怪,他是彻底傻了,一秒前还记给人袭击,然后还要梦到温馨和重生的夜莺,但是,他的确清醒了。

如出一辙年后小林俊介离开了奈良去矣扳平幢海滨城市,走前头拜访了年已经双稀的父母,家具意见吧尚无带。在新的城池,小林俊介按照好之艺术在正在,收留流浪的动物,施舍乞丐,并且和部分总人口做了恋人,小林俊介知道,只有和睦放弃了几乎班自己之物,他才会无所畏惧,只有征服和搜索,他的光阴才会继承。他未会见又错过开片失败品的傀儡,给自己之自卑加同项外衣,更不见面畏首畏尾了。小林俊介自生他的上帝,上帝就让他使过去平仅仅夜莺。

输入输出样例

输入样例#1:

3
10 2 3
2 3 4
3 4 5
2 2 2
3 5 3
4 5 1
输出样例#1:

52

思路


代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 40
#define maxn 9999999
using namespace std;
int n,a[N][N],b[N][N],love[N][N];
bool vis_boy[N],vis_girl[N];
int pre[N],remain[N],ex_girl[N],ex_boy[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
int dfs(int girl)
{
    vis_girl[girl]=true;
    for(int i=1;i<=n;i++)
    {
        if(vis_boy[i]) continue;
        int ex=ex_boy[i]+ex_girl[girl]-love[girl][i];
        if(ex==0) 
        {
            vis_boy[i]=true;
            if(pre[i]==-1||dfs(pre[i]))
            {pre[i]=girl; return 1;}
        }
        else remain[i]=min(remain[i],ex);
    }
    return false;
}
int km()
{
    memset(ex_boy,0,sizeof(ex_boy));
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      ex_girl[i]=max(ex_girl[i],love[i][j]);
    for(int i=1;i<=n;i++)
    {
        memset(remain,0x7fff,sizeof(remain));
        while(1)
        {
            memset(vis_boy,0,sizeof(vis_boy));
            memset(vis_girl,0,sizeof(vis_girl));
            if(dfs(i)) break;
            int d=maxn;
            for(int i=1;i<=n;i++)
             if(!vis_boy[i]) d=min(d,remain[i]);
            for(int i=1;i<=n;i++)
            {
                if(vis_boy[i]) ex_girl[i]-=d;
                if(vis_girl[i]) ex_boy[i]+=d;
                else remain[i]-=d;
            }
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
     ans+=love[pre[i]][i];
    return ans;
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      a[i][j]=read();
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      b[i][j]=read();
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      love[i][j]=a[i][j]*b[j][i];
   printf("%d\n",km());
   return 0;
 } 

 

#include<cstdio>
#include<iostream>
#define MAXN 110
#define INF 1000000000
using namespace std;
int lx[MAXN],ly[MAXN];
int f[MAXN][MAXN],n,m,pre[MAXN],pre2[MAXN];
bool vx[MAXN],vy[MAXN];
inline void read(int&x) {
    int f=1;x=0;char c=getchar();
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=10*x+c-48,c=getchar();
    x=x*f;
}
inline void pra() {
    for(int i=1;i<=n;i++) 
      for(int j=1;j<=m;j++)
        lx[i]=max(lx[i],f[i][j]);
}
inline bool find(int u) {
    vx[u]=true;
    for(int i=1;i<=m;i++) {
        if(lx[u]+ly[i]==f[u][i]&&!vy[i]) {
            vy[i]=true;
            if(!pre[i]||find(pre[i])) {
                pre[i]=u;
                pre2[u]=i;
                return true;
            }
        }
    }
    return false;
}
inline void renew() {
    int t=INF;
    for(int i=1;i<=n;i++)
      if(vx[i])
        for(int j=1;j<=m;j++)
          if(!vy[j])
            t=min(t,lx[i]+ly[j]-f[i][j]);
    for(int i=1;i<=n;i++)
      if(vx[i]) lx[i]-=t;
    for(int j=1;j<=m;j++)
      if(vy[j]) ly[j]+=t;
}
inline void km() {
    for(int i=1;i<=n;i++) 
    while(true){
        for(int j=1;j<=n;j++) vx[j]=false;
        for(int j=1;j<=m;j++) vy[j]=false;
        if(find(i)) break;
        else renew();
    }
}
int main() {
    read(n);read(m);
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        read(f[i][j]);
    pra();
    km();
    int ans=0;
    for(int i=1;i<=n;i++)
      ans+=f[i][pre2[i]];
    printf("%d\n",ans);
    return 0;
}