1028 花店橱窗布置 (带权二分图的最大匹配)

来源:互联网 发布:微信扫码群发软件下载 编辑:程序博客网 时间:2024/06/09 21:04

题目描述 Description

假设以最美观的方式布置花店的橱窗,有F束花,V个花瓶,我们用美学值(一个整数)表示每束花放入每个花瓶所产生的美学效果。为了取得最佳的美学效果,必须使花的摆放取得最大的美学值。

输入描述 Input Description

第一行为两个整数F,V(F<=V<=100)接下来F行每行V个整数,第i行第j个数表示第i束花放入第j个花瓶的美学值。

输出描述 Output Description

一个整数,即最大美学值。

样例输入 Sample Input

2 210 05 2

样例输出 Sample Output

12

数据范围及提示 Data Size & Hint

裸地KM算法

代码:

#include<cstdio>#include<iostream>#define MAXN 110#define INF 1000000000using 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;}
0 0
原创粉丝点击