POJ_1251链接 (最小生成树问题)
我写的是java代码、关于java自定义类型的编译器的、我弄了好久、现在总算通过了、自己也get了一个新知识、哈哈
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;
public class POJ_1251_Kruskal {
static int len, n;
static Node[] node = new Node[80];
static HashMap<String, String> fatherMap = new HashMap<String, String>(); // POJ 这里后面不能呢使用菱形运算符、会编译错误
static LinkedList<Node> listNode = new LinkedList<Node>(); // POJ 这里后面不能呢使用菱形运算符、会编译错误
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
listNode.clear();
len = 0;
n = input.nextInt();
if (n == 0) {
break;
}
for (int i = 0; i < n - 1; i++) {
String u = input.next(); // 当前结点、、、
fatherMap.put(u, u); // 当前结点的父节点是自己、、、
int num = input.nextInt(); // 能链接的岛屿的数量、、
if (num == 0) {
continue;
}
for (int k = 0; k < num; k++) { // 与该岛屿连接的岛屿的信息、、、
String v = input.next();
fatherMap.put(v, v); // 当前结点的父节点 还是自己、、
int cost = input.nextInt();
listNode.add(new Node(u, v, cost));
len++; // 并且这个 记录边的总个数、、
}
} // 岛屿输入的结束、、
Collections.sort(listNode, new MyComparator()); // 用自己的定义的比较器初始化、、
kruskal(listNode);
}
}
private static void kruskal(LinkedList<Node> list) {
int q = 0; // 添加的边数、、
int ans = 0; // 花费、、
for(int i = 0; i < len; i++){
Node node = listNode.poll();
if(Find(node.u) != Find(node.v)){
ans += node.value;
Union(node.u, node.v);
q++;
}
if(q == n - 1) break;
}
System.out.println(ans);
}
public static void Union(String u, String v){
String uFather = fatherMap.get(u);
String vFather = fatherMap.get(v);
if(uFather != vFather){
fatherMap.put(uFather, vFather); // 合并起来、、
}
}
public static String Find(String s){
String father = fatherMap.get(s);
if(father != s){
father = Find(father);
}
fatherMap.put(s, father);
return father;
}
public static class MyComparator implements Comparator<Node> { // 自己定义的比较器、、、
@Override
public int compare(Node a, Node b) {
return a.value - b.value;
}
}
static class Node {
String u, v;
int value;
public Node() {
}
public Node(String u, String v, int value) {
this.u = u;
this.v = v;
this.value = value;
}
}
}
Prim算法注意的需要添加正反两个权重、
import java.util.Scanner;
public class POJ_1251_Prim {
static final int INF = 0x3f3f3f;
static int [][] map = new int [30][30];
static boolean [] vis = new boolean [30]; // 用来标记有没有使用过的、、
static int [] mincost = new int [30];
static int n;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
Init();
n = input.nextInt();
if(n == 0) break;
for(int i = 0; i < n - 1; i++){ //
String u = input.next();
int unum = u.charAt(0) - 'A';// 总算转化出来了 、 java大法好、、、
int num = input.nextInt();
if(num == 0) continue;
for(int k = 0; k < num; k++){
String v = input.next(); // 对应的边、、
int cost = input.nextInt(); // 权重 、、、
int vnum = v.charAt(0) - 'A';
map[unum][vnum] = map[vnum][unum] = cost; // Prim 无向边、两个都要添加、、
}
}
int res = Prim();
System.out.println(res);
}
}
public static int Prim(){
// for(int i = 0; i < n; i++){ // 有也可以、没有也可以、、方便你们理解、、
// vis[i] = false;
// mincost[i] = map[0][i];
// }
mincost[0] = 0; // 起始位置为 0 、、
int res = 0;
while(true){
int v = -1;
for(int u = 0; u < n; u++){
if(!vis[u] && (v == -1 || mincost[u] < mincost[v])){
v = u; // 找出当前最短的路径、、
}
}
if(v == -1) break;
vis[v] = true;
res += mincost[v]; // 加上当前的长度、、、
for(int u = 0; u < n; u++){
mincost[u] = Math.min(mincost[u], map[v][u]);
}
}
return res;
}
public static void Init(){
for(int i = 0; i < 30; i++){
vis[i] = false;
mincost[i] = INF;
for(int j = 0; j < 30; j++){
map[i][j] = INF;
}
}
}
}