您的位置:首页 > 其它

zoj 2158 poj 1789 Truck History (Prim)

2013-11-27 19:56 232 查看
题目大意:

高级货物运输公司ACM使用不同类型的卡车。有些卡车用来运蔬菜,有些用来运水果,还有一些用来运砖,等等。该公司对不同的卡车有自己的编码方法。卡车的编码为一个包含7个字符的字符串(每个位置上的字符都有特定的含义,但这一点对本题并不重要)。在ACM公司发展历史上的初期,只有一种卡车可供使用,只有一种卡车类型编码;后来又引进了新的一种卡车类型,新卡车的类型编码是从第一种卡车编码派生出来的;然后新的卡车类型编码又派生出其他卡车类型编码,等等。

今天,ACM公司是如此的富有,可以让历史学家来研究公司的历史。历史学家试图弄明白的一件事情被称为派生方案,也就是,卡车的类型是如何派生的。他们将卡车类型编码的距离定义成卡车类型编码字符串中(7个位置上)不同字符的位置数目。比如,一个卡车编码是aaaaaaa,另一个卡车编码是babaaaaa,那么他们的距离值就是2。他们假定每种卡车类型都是由其他一种卡车类型派生出来的,当然,第一种卡车类型除外,它不是由任何其他一种类型派生的。派生方案的优劣值定义成:



其中,求和部分为派生方案中所有类型对(to, td)的距离,to为基类型,td为派生出来的类型。因为ACM公司卡车类型很多,历史学家很难判断这些类型编码之间派生关系。本题的目的是要求编写程序,实现:给定卡车类型的编码,求具有最高优劣值的派生方案。

题目太扯了,本题就是求:



最小值,而他就是最小生成树权值之和。这里用Prim思想解决的。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int INF = 10000010;
const int MAXN = 2010;
int n;
int lowcost[MAXN];
int Edge[MAXN][MAXN];
char codes[MAXN][10];

void Inite()
{
int i, j, k;

for(i = 0; i < n; ++i)
cin>>codes[i];

memset(Edge, 0, sizeof(Edge));
for (i = 0; i < n; ++i)
{
for (j = i+1; j < n; ++j)
{
int dist = 0;
for(k = 0; k < 7; ++k)
if(codes[i][k] != codes[j][k])
dist++;
Edge[i][j] = Edge[j][i] = dist;
}
}
memset(lowcost, 0, sizeof(lowcost));
}

void Prim()
{
int i, j;
int sum = 0;
for(i = 0; i < n; ++i)
lowcost[i] = Edge[0][i];
lowcost[0] = -1;

for (i = 1; i < n; ++i)
{
int MIN = INF, v = -1;
for (j = 0; j < n; ++j)
{
if(lowcost[j] != -1 && MIN > lowcost[j])
{
v = j;
MIN = lowcost[j];
}
}
sum += MIN;
lowcost[v] = -1;
for (j = 0; j < n; ++j)
{
if(lowcost[j] != -1 && lowcost[j] > Edge[v][j])
lowcost[j] = Edge[v][j];
}
}
cout<<"The highest possible quality is 1/"<<sum<<"."<<endl;
}
int main()
{
while (cin>>n && n)
{
Inite();
Prim();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: