poj 1789 卡车编号

来源:互联网 发布:华北计算机研究所java 编辑:程序博客网 时间:2024/04/27 23:56

题意:求一种编号方式使得所有不同类型卡车权值最小

 

题意大概是这样的:用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数。一个编号只能由另一个编号衍生出来,代价是这两个编号之间相应的distance,现在要找出一个衍生方案,使得总代价最小,也就是distance之和最小。

例如有如下4个编号:

aaaaaaa

baaaaaa

abaaaaa

aabaaaa

显然的,第二,第三和第四编号分别从第一编号衍生出来的代价最小,因为第二,第三和第四编号分别与第一编号只有一个字母是不同的,相应的distance都是1,加起来是3。也就是最小代价为3

问题可以转化为最小代价生成树的问题。因为每两个结点之间都有路径,所以是完全图。 

参考:http://blog.csdn.net/lyy289065406/article/details/6645974

#include <iostream>#include <sstream>#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <vector>#include <set>#include <cctype>#include <algorithm>#include <cmath>#include <deque>#include <queue>#include <map>#include <queue>#include <list>#include <iomanip>using namespace std;                                               //////const int INF =  20000000;   #define maxn 2012   #define max(a,b)(a>b?a:b)///int n;char str[maxn][8];int dist[maxn][maxn];int weight(int i,int j){int w = 0;int k;for (k = 0; k < 7; k++){if (str[i][k] != str[j][k])w++;}return w;}int prim(){int i, j;int s = 1;//源点int m = 1;//最小生成树顶点个数bool u[maxn];//判定是否属于最小生成树int prim_w = 0;  //最小生成树的总权值 int min_w;     //每个新源点到其它点的最短路int flag_point;int low_dis[maxn];  //各个源点到其它点的最短路 //memset(low_dis, INF, sizeof(low_dis));for (i = 1; i <= n; i++){low_dis[i] = INF;}memset(u, false, sizeof(u));u[s] = true;while (1){if (m == n)break;min_w = INF;for (j = 2; j <= n; j++){//更新操作if (!u[j] && low_dis[j] > dist[s][j])low_dis[j] = dist[s][j];if (!u[j] && min_w > low_dis[j]){min_w = low_dis[j];flag_point = j;}}s = flag_point;//新的源点u[s] = true;prim_w += min_w;m++;}return prim_w;}int main(){freopen("F:\\input.txt","r",stdin );///int i, j;while (1){cin >> n;if (n == 0)break;for (i = 1; i <= n; i++)cin >> str[i];//建立邻接图for (i = 1; i <= n - 1; i++){for (j = i + 1; j <= n; j++){dist[i][j] = dist[j][i] = weight(i, j);}}//计算cout<<"The highest possible quality is 1/"<< prim() <<'.'<<endl; }///    return 0;}