POJ 1789 Truck History的Prim算法

package pro.proclass.chaopengfan;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class VjudgeH {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (br.ready()) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            if(n==0)break;
            String[] data = new String[n];
            int[][] map = new int[n][n]; //所有卡车相互转换所需要的衍生距离

            for (int i = 0; i < n; i++) {
                st = new StringTokenizer(br.readLine());
                data[i] = st.nextToken();
            }

            // 初始化所有卡车之间的距离
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    if(i==j)continue; // 卡车自己不需要衍生
                    int dis = 0;

                    // 计算卡车i和卡车j之间不同的字母位置个数
                    for (int k = 0; k < 7; k++) {
                        if(data[i].charAt(k) != data[j].charAt(k))
                            dis++;
                    }

                    map[i][j] = dis;
                }
            }

            int ans = 0;
            // 开始prim算法
            int[] distance = new int[n]; // 存储到点i的最短距离的边权值。
            //开始随便从一个点开始。我这里从0点走
            // 初始化distance
            for (int i = 0; i < n; i++) {
                distance[i] = map[0][i]; // 0点到其他所有点的距离
            }

            boolean[] visited = new boolean[n]; //存储哪些点的最短权边已经找到
            visited[0] = true; // 从0点开始走,不需要找

            for (int i = 0; i < n; i++) { // 最多可能需要找n-1次最短距离边
                int node = -1;
                int min = Integer.MAX_VALUE;
                for (int j = 0; j < n; j++) { // 查找distance最短边点的权值
                    if(distance[j] < min && !visited[j]) {
                        min = distance[j];
                        node = j;
                    }
                }

                if(min == Integer.MAX_VALUE) break;
                visited[node] = true;
                ans += min;

                for (int j = 0; j < n; j++) {
                    // 寻找结束点node对应边的权值,存储较小的权
                    if(!visited[j] && distance[j] > map[node][j]) {
                        distance[j] = map[node][j];
                    }
                }
            }

            System.out.println(String.format("The highest possible quality is 1/%d.", ans));
        }
    }
}

  

posted @ 2020-09-28 16:49  姓蜀名黍  阅读(122)  评论(0)    收藏  举报