最小生成树(Prim)(普利姆最小生成树)
2016-10-06 20:54
176 查看
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
import com.sun.corba.se.impl.oa.poa.ActiveObjectMap.Key;
import com.sun.scenario.effect.impl.prism.PrImage;
public class Test {
static Vertex[] v;
// 就是用于记录用户要输入多少条边关系的,其他没什么╮(╯▽╰)╭
static int mark = 0;
static int sum = 0;
static int[] dis;
static int key;
static final int MINVAL = 9999999;
static int min = MINVAL;
// 用于记录这个顶点是否已经选择过了
static int[] book;
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(System.in);
v = new Vertex[scanner.nextInt() + 1];
dis = new int[v.length];
book = new int[v.length];
mark = scanner.nextInt();
for (int i = 0; i < v.length; i++) {
v[i] = new Vertex();
// 不过从哪个点开始,一开始默认所有的距离都是MINVAL
dis[i] = min;
}
int temp1 = 0;
int temp2 = 0;
int temp3 = 0;
Edge edge = null;
for (int i = 0; i < mark; i++) {
temp1 = scanner.nextInt();
temp2 = scanner.nextInt();
temp3 = scanner.nextInt();
edge = new Edge(temp1, temp2, temp3);
v[temp1].getEdges().add(0, edge);
edge = new Edge(temp2, temp1, temp3);
v[temp2].getEdges().add(0, edge);
}
// 假定从1号顶点开始扩展生成树
book[1] = 1;
temp1 = v[1].getEdges().size();
for (int i = 0; i < temp1; i++) {
edge = v[1].getEdges().get(i);
dis[edge.getEnd()] = edge.getWeight();
}
prim();
System.out.println(sum);
scanner.close();
}
private static void prim() {
int count = 0;
while(true){
min = MINVAL;
// 先选取出dis中的最小值,这个就是当前最好的顶点,用它来做下一轮的中间点
for (int i = 0; i < dis.length; i++) {
if (book[i] == 0 && min > dis[i]) {
min = dis[i];
key = i;
}
}
book[key] = 1;
sum += min;
count++;
// 本来是应该减1的,但是因为从下标从1开始的关系,所以这里要减2
if (count == v.length - 2) {
break;
}
// 以中间点为拓展,开始展开下一步的“松弛”
LinkedList<Edge> edges = v[key].getEdges();
Edge edge;
for (int i = 0; i < edges.size(); i++) {
edge = edges.get(i);
// 需要注意的是,这里的book[edge.getEnd()] == 0非常重要,这是为了保证不形成回路的根本。
// 因为当book[edge.getEnd()] == 1时,表明前边已经加其加入生成树之中了,它已经做过中转点了。
// 然后需要注意的就是edge.getWeight() < dis[edge.getEnd()],这里之所以这样写,有两个方面的原因吧。
// 第一个原因:因为dis这时候记录的是下一个可能的中转点到这棵生成树里面每一个节点的距离,所以这样写即可
// 而不是像迪杰斯特拉一样,需要dis[xx] + edge.getWeight() < dis[xxx]这种形式
// 第二个原因嘛:就是注意edge.getEnd()这里不要写成edge.getBegin了,这样的话,你不断改变的都是这是一个地方的dis值
// 而且这个dis的值已经被book【xx】所阻挡了= =
if (book[edge.getEnd()] == 0 && edge.getWeight() < dis[edge.getEnd()]) {
dis[edge.getEnd()] = edge.getWeight();
}
}
}
}
}
class Vertex {
private LinkedList<Edge> edges = new LinkedList<>();
private int id;
public Vertex() {
}
public LinkedList<Edge> getEdges() {
return edges;
}
public void setEdges(LinkedList<Edge> edges) {
this.edges = edges;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class Edge implements Comparable<Edge> {
private int begin;
private int end;
private int weight;
public Edge() {
}
public Edge(int begin, int end, int weight) {
this.begin = begin;
this.end = end;
this.weight = weight;
}
public int getBegin() {
return begin;
}
public void setBegin(int begin) {
this.begin = begin;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Edge [begin=" + begin + ", end=" + end + ", weight=" + weight
+ "]";
}
@Override
public int compareTo(Edge o) {
if (this.weight > o.getWeight()) {
return 1;
}
return -1;
}
}
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
import com.sun.corba.se.impl.oa.poa.ActiveObjectMap.Key;
import com.sun.scenario.effect.impl.prism.PrImage;
public class Test {
static Vertex[] v;
// 就是用于记录用户要输入多少条边关系的,其他没什么╮(╯▽╰)╭
static int mark = 0;
static int sum = 0;
static int[] dis;
static int key;
static final int MINVAL = 9999999;
static int min = MINVAL;
// 用于记录这个顶点是否已经选择过了
static int[] book;
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(System.in);
v = new Vertex[scanner.nextInt() + 1];
dis = new int[v.length];
book = new int[v.length];
mark = scanner.nextInt();
for (int i = 0; i < v.length; i++) {
v[i] = new Vertex();
// 不过从哪个点开始,一开始默认所有的距离都是MINVAL
dis[i] = min;
}
int temp1 = 0;
int temp2 = 0;
int temp3 = 0;
Edge edge = null;
for (int i = 0; i < mark; i++) {
temp1 = scanner.nextInt();
temp2 = scanner.nextInt();
temp3 = scanner.nextInt();
edge = new Edge(temp1, temp2, temp3);
v[temp1].getEdges().add(0, edge);
edge = new Edge(temp2, temp1, temp3);
v[temp2].getEdges().add(0, edge);
}
// 假定从1号顶点开始扩展生成树
book[1] = 1;
temp1 = v[1].getEdges().size();
for (int i = 0; i < temp1; i++) {
edge = v[1].getEdges().get(i);
dis[edge.getEnd()] = edge.getWeight();
}
prim();
System.out.println(sum);
scanner.close();
}
private static void prim() {
int count = 0;
while(true){
min = MINVAL;
// 先选取出dis中的最小值,这个就是当前最好的顶点,用它来做下一轮的中间点
for (int i = 0; i < dis.length; i++) {
if (book[i] == 0 && min > dis[i]) {
min = dis[i];
key = i;
}
}
book[key] = 1;
sum += min;
count++;
// 本来是应该减1的,但是因为从下标从1开始的关系,所以这里要减2
if (count == v.length - 2) {
break;
}
// 以中间点为拓展,开始展开下一步的“松弛”
LinkedList<Edge> edges = v[key].getEdges();
Edge edge;
for (int i = 0; i < edges.size(); i++) {
edge = edges.get(i);
// 需要注意的是,这里的book[edge.getEnd()] == 0非常重要,这是为了保证不形成回路的根本。
// 因为当book[edge.getEnd()] == 1时,表明前边已经加其加入生成树之中了,它已经做过中转点了。
// 然后需要注意的就是edge.getWeight() < dis[edge.getEnd()],这里之所以这样写,有两个方面的原因吧。
// 第一个原因:因为dis这时候记录的是下一个可能的中转点到这棵生成树里面每一个节点的距离,所以这样写即可
// 而不是像迪杰斯特拉一样,需要dis[xx] + edge.getWeight() < dis[xxx]这种形式
// 第二个原因嘛:就是注意edge.getEnd()这里不要写成edge.getBegin了,这样的话,你不断改变的都是这是一个地方的dis值
// 而且这个dis的值已经被book【xx】所阻挡了= =
if (book[edge.getEnd()] == 0 && edge.getWeight() < dis[edge.getEnd()]) {
dis[edge.getEnd()] = edge.getWeight();
}
}
}
}
}
class Vertex {
private LinkedList<Edge> edges = new LinkedList<>();
private int id;
public Vertex() {
}
public LinkedList<Edge> getEdges() {
return edges;
}
public void setEdges(LinkedList<Edge> edges) {
this.edges = edges;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class Edge implements Comparable<Edge> {
private int begin;
private int end;
private int weight;
public Edge() {
}
public Edge(int begin, int end, int weight) {
this.begin = begin;
this.end = end;
this.weight = weight;
}
public int getBegin() {
return begin;
}
public void setBegin(int begin) {
this.begin = begin;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Edge [begin=" + begin + ", end=" + end + ", weight=" + weight
+ "]";
}
@Override
public int compareTo(Edge o) {
if (this.weight > o.getWeight()) {
return 1;
}
return -1;
}
}
相关文章推荐
- 最小生成树——Prim(普利姆)算法
- java实现图的最小生成树(MST)的普利姆(Prim)算法
- 最小生成树——Prim(普利姆)算法
- 15分钟掌握最小生成树普利姆(Prim)算法
- hdu1863 畅通工程(最小生成树之prim)
- hdu1863 畅通工程(最小生成树之prim)
- 生成树最小生成树poj 1258 prim
- 最小生成树之Prim(普里姆)算法
- poj 1258 prim最小生成树
- 最小生成树 prim 算法 与kruskal 算法
- 最小生成树算法prim and kruskal
- HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)
- HDU1863 畅通project 【最小生成树Prim】
- POJ 1287 Networking [prim求解最小生成树]
- 最小生成树 Prim
- Prim最小生成树算法
- 最小生成树poj1258 prim和kruskal
- 杭电3371 Connect the Cities(最小生成树 prim)
- acm pku 1287 Networking的Prim最小生成树算法实现
- prim求最小生成树——Highways