您的位置:首页 > 其它

CODE[VS]1028 花店橱窗布置

2017-10-23 16:24 405 查看
题目:http://codevs.cn/problem/1028/

思路:KM算法求解

题解:

/* 1028 花店橱窗布置 */
#include <stdio.h>

#define MAXN 101
#define max(X,Y) ((X>Y)?X:Y)
#define min(X,Y) ((X<Y)?X:Y)
#define INF 2147483647
int F, V;                       /* 花束数,花瓶数 */
int aesthetics[MAXN][MAXN];     /* 花束-花瓶美学值对应表 */
int linky[MAXN], visx[MAXN], visy[MAXN], lack;
int lx[MAXN] = {0}, ly[MAXN] = {0};
int maxans;                     /* 最大美学值 */

/* 匈牙利算法 */
int find(int x)
{
int y;
int t;
/* 标记花束x已访问 */
visx[x] = 1;
for(y = 1; y <= V; y++)
{
/* 如果花瓶y已使用,继续下一次循环 */
if(1 == visy[y])
{
continue;
}
/* 计算是否匹配 */
t = lx[x] + ly[y] - aesthetics[x][y];
if(0 == t)
{
visy[y] = 1;
if(0 == linky[y] || 1 == find(linky[y]))
{
linky[y] = x;
return 1;
}
}
else
{
lack = min(lack, t);
}
}
return 0;
}

/* KM算法 */
void km()
{
int fi, vi, i;
/* 初始化链接关系 */
for(vi = 1; vi <= V; vi++)
{
linky[vi] = 0;
}
/* 初始化花束顶标值 */
for(fi = 1; fi <= F; fi++)
{
for(vi = 1; vi <= V; vi++)
{
lx[fi] = max(lx[fi], aesthetics[fi][vi]);
}
}
/* 初始化花瓶顶标值 */
for(vi = 1; vi <= V; vi++)
{
ly[vi] = 0;
}
/* 求完备匹配 */
for(fi = 1;  fi <= F; fi++)
{
for(;;)
{
/* 清零访问标记 */
for(i = 1; i <= V; i++)
{
visx[i] = 0;
visy[i] = 0;
}
lack = INF;
if(1 == find(fi))
{
break;
}
/* 修改已访问点顶标值 */
for(i = 1; i <= V; i++)
{
if(1 == visx[i])
{
lx[i] = lx[i] - lack;
}
if(1 == visy[i])
{
ly[i] = ly[i] + lack;
}
}
}
}
/* 测试 - 打印顶标值及对应表 */
/*
printf("花瓶-花束对应表:\n");
for(vi = 1; vi <= V; vi++)
{
if(0 != linky[vi])
{
printf("V[%2d](%2d) -> F[%2d](%2d)\n", vi, ly[vi], linky[vi], lx[linky[vi]]);
}
}
*/
/******************/
}

/* 主函数入口 */
int main()
{
int fi, vi;         /* 索引值 */
/* 打开数据文件 */
FILE *fp;
if(NULL == (fp = fopen("data.txt", "r")))
{
return 1;
}
/***************/

/* 获取花束数,花瓶数 */
fscanf(fp, "%d %d", &F, &V);
/* 获取对应美学值 */
for(fi = 1; fi <= F; fi++)
{
for(vi = 1; vi <= V; vi++)
{
fscanf(fp, "%d", &aesthetics[fi][vi]);
}
}
km();
maxans = 0;
for(vi = 1; vi <= V; vi++)
{
maxans = maxans + aesthetics[linky[vi]][vi];
}
/* 打印结果 */
printf("%d", maxans);
/* 关闭数据文件 */
fclose(fp);
/****************/
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: