题目链接:
https://vjudge.net/problem/POJ-1789
题目大意:
用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数。一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小。
思路:
最小生成树模板题,这里是稠密图,应该用prim算法
直接在原来模板的基础上稍加改动即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<stack> 8 #include<map> 9 #include<sstream> 10 using namespace std; 11 typedef long long ll; 12 const int maxn = 2e3 + 10; 13 const int INF = 1 << 30; 14 int dir[4][2] = {1,0,0,1,-1,0,0,-1}; 15 int T, n, m, x; 16 int Map[maxn][maxn];//存图 17 int lowcost[maxn], mst[maxn]; 18 void prim(int u)//最小生成树起点 19 { 20 int sum_mst = 0;//最小生成树权值 21 for(int i = 1; i <= n; i++)//初始化两个数组 22 { 23 lowcost[i] = Map[u][i]; 24 mst[i] = u; 25 } 26 mst[u] = -1;//设置成-1表示已经加入mst 27 for(int i = 1; i <= n; i++) 28 { 29 int minn = INF; 30 int v = -1; 31 //在lowcost数组中寻找未加入mst的最小值 32 for(int j = 1; j <= n; j++) 33 { 34 if(mst[j] != -1 && lowcost[j] < minn) 35 { 36 v = j; 37 minn = lowcost[j]; 38 } 39 } 40 if(v != -1)//v=-1表示未找到最小的边, 41 {//v表示当前距离mst最短的点 42 //printf("%d %d %d ", mst[v], v, lowcost[v]);//输出路径 43 mst[v] = -1; 44 sum_mst += lowcost[v]; 45 for(int j = 1; j <= n; j++)//更新最短边 46 { 47 if(mst[j] != -1 && lowcost[j] > Map[v][j]) 48 { 49 lowcost[j] = Map[v][j]; 50 mst[j] = v; 51 } 52 } 53 } 54 } 55 //printf("weight of mst is = %d ", sum_mst); 56 printf("The highest possible quality is 1/%d. ", sum_mst); 57 } 58 string s[maxn]; 59 int sum(int i, int j) 60 { 61 int tot = 0; 62 for(int k = 0; k < 7; k++) 63 { 64 if(s[i][k] != s[j][k])tot++; 65 } 66 return tot; 67 } 68 int main() 69 { 70 while(cin >> n && n) 71 { 72 for(int i = 1; i <= n; i++)cin >> s[i]; 73 for(int i = 1; i <= n; i++) 74 { 75 for(int j = 1; j <= n; j++) 76 { 77 Map[i][j] = sum(i, j); 78 } 79 } 80 prim(1); 81 } 82 return 0; 83 }