题意:
给出N个城镇的坐标和M条已经建好的路, 求连接所有城镇且长度之和最小的高速公路系统的每条公路, 已经存在的公路不用输出。
样例:
Sample Input
9 (城镇个数及坐标)
1 5
0 0
3 2
4 5
5 1
0 4
5 2
1 2
5 3
3 //M条已建好的路,城镇1-->3,9--->7,1--->2
1 3
9 7
1 2
Sample Output
1 6
3 7
4 9
5 7
8 3
由于最后不用输出长度值, 而且坐标的绝对值不超过10000, 所以在算城镇距离的时候就直接省去了sqrt(),由于需要输出MST的边, 所以开了preVex[]记录每个结点的前驱结点, 默认值都为1. 每次选到新的扩展结点min_i后, 若连接它的边权值不为-1, 即这条路是新修建的, 则输出这条边. 然后如果min_i到MST外的某一结点i的权值, 比MST中其它结点到i的权值还要小, 那么更新dis[1][i]): dis[1][i]=dis[min_i][i], 然后顺带更新preVex[i]为min_i.
import java.util.Scanner;
public class Main{
private int dis[][];//邻接矩阵
private int n;//城镇的个数
private boolean vis[]; //城镇已加入到MST的标志
public Main(int n,int[][] dis){
this.n=n;
this.dis=dis;
vis=new boolean[n+1];
}
static int DIS(int x1,int y1,int x2,int y2){//计算两城镇的距离(权)
return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
private void prim(){
int preVex[]=new int[n+1];
vis[1]=true; //城镇1已加入到MST
for(int i=1;i<=n;i++) preVex[i]=1;
for(int k=1;k<n;k++){
int min_i=1;
int min = Integer.MAX_VALUE;
for(int i=1;i<=n;i++){
if(!vis[i] &&dis[1][i]<min) {
min=dis[1][i];
min_i=i;
}
}
vis[min_i]=true; //城镇min_i已加入到MST
if(dis[1][min_i]!=-1) System.out.printf("%d %d\n",preVex[min_i],min_i);
for(int i=1;i<=n;++i)
if(!vis[i] && dis[min_i][i]<dis[1][i]){
dis[1][i]=dis[min_i][i];
preVex[i]=min_i;
}
}
}
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int[][] dis=new int[n+1][n+1];
int x[]=new int[n+1];
int y[]=new int[n+1];
for(int i=1;i<=n;i++){//n个城镇的坐标
x[i]=in.nextInt();
y[i]=in.nextInt();
}
int m=in.nextInt();//m条已建好的公路
int u,v;
for(int i=1;i<=m;++i){
u=in.nextInt();
v=in.nextInt();
dis[u][v]=dis[v][u]=-1; //城镇u与v之间已有公路,他们的距离设为-1,必进最小生成树
}
for(int i=1;i<n;++i) {
for(int j=i+1;j<=n;++j)
if(dis[i][j]==0)
dis[j][i]=dis[i][j]=DIS(x[i],y[i],x[j],y[j]);
}
new Main(n,dis).prim();
}
}
分享到:
相关推荐
标题中的“POJ 1789 最小生成树之prim算法”指的是一个在线编程竞赛题目,来源于普林斯顿开放在线课程(POJ)平台。该题目要求参赛者实现Prim算法,这是一种解决图论问题中寻找最小生成树的经典算法。最小生成树是在...
标题“poj1251 最小生成树”是一个编程竞赛题目,来源于著名的在线编程平台POJ(Programming Online Judge)。这个题目主要涉及图论中的一个经典算法问题——最小生成树(Minimum Spanning Tree, MST)。在图论中,...
Prim算法是一种用于求解图中最小生成树的算法。在图论中,一个连通图的最小生成树是一棵树,它包含图中的所有顶点,并且所有边的权重之和尽可能小。Prim算法是从一个顶点开始,逐步添加边,直到包含所有顶点,每次...
Prim算法可以帮助找到连接所有城市的最短路径总和,即最小生成树。 总的来说,这个压缩包提供了对POJ2485题目的完整解答,通过Prim算法解决了公路网络优化的问题,并附有详细的代码和解题思路。对于学习图论和算法...
Prim算法是一种贪心算法,其基本思想是从某个顶点出发,逐步选择与当前已构建的生成树相连接的边中权重最小的边加入生成树中,直到生成树包含图中的所有顶点为止。 - **初始化**:选择一个顶点\( v \)作为起始顶点...
对于这些题目,理解最小生成树的基本算法如 Prim 和 Kruskal 是关键,同时要注意根据具体问题的特性调整算法的应用。在实际编程时,还需要注意数据结构的选择,例如使用优先队列(二叉堆)优化 Prim 算法,或者使用...
普里姆算法是一种贪心算法,它从一个顶点开始,逐步扩展最小生成树,每次添加一条与当前生成树连接且权值最小的边。以下是算法的基本步骤: 1. 初始化:选择图中的任意一个顶点作为初始最小生成树的一部分。 2. 建立...
给定代码片段中使用了Prim算法来计算每个连通分量内的最小生成树,并通过扩展Prim算法(`extend_degree()`函数)来寻找每个连通分量中到根节点的最佳边,以此来构建满足度数限制的生成树。 #### 知识点三:代码分析...
【Prim算法】Prim算法是一种贪心策略,用于解决图论中的最小生成树问题。它从一个初始顶点开始,逐步添加边,每次选择与当前树连接且权重最小的边,直到所有顶点都被包含在内。Prim算法有多种实现方式,如优先队列...
* 最小生成树算法:最小生成树算法是指计算图的最小生成树的算法,如 prim、kruskal。 * 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大...
然后,Prim算法每次从尚未加入最小生成树的节点中选择距离起点最近的一个,连接到树中,更新其他节点的距离。重复此过程,直至所有节点都被包含在内。 在提交的代码文件“POJ3026-Borg Maze【BFS+Prim】.cpp”中,...
1. **函数mst(int ss)**:输入参数ss代表生成树的起点,该函数通过Prim算法实现最小生成树的构建。 - 初始化距离数组`dis[]`,设置起点距离为0,其余节点距离为无穷大。 - 使用循环找到未加入生成树的最近节点,并...
常见的求解最小生成树的算法有Prim算法和Kruskal算法。 1. **Prim算法**:从一个顶点开始,逐步添加边,每次添加的边连接两个不同的连通分量,并且具有当前未加入树的边中的最小权重,直到连接所有顶点为止。 2. *...
先利用prim算法求出最小生成树,然后通过往MST里加边来判断新生成的最小生成树是否具有最小的权值,POJ上The Unique MST(1679)题是要求判断最小生成树是否唯一,此题其实根本不用这样做,但是为了练习球次小生成树...
1. **Prim算法**:Prim算法是一种贪心策略,从一个初始顶点开始,逐步添加最便宜的边,使得每次添加的新边都连接到已有的最小生成树。这个过程持续到所有顶点都被包含在内。Prim算法在稠密图中效率较高,因为它每次...
prim算法是一种贪心算法,用于计算图的最小生成树。Stoer-Wagner 算法将prim算法应用于计算图的最小割。 Stoer-Wagner 算法的实现可以分为以下步骤: 1. 初始化图的邻接矩阵mat和deleted数组,deleted数组用于标记...
* 最小生成树算法:prim、kruskal、POJ1789、POJ2485、POJ1258、POJ3026 * 拓扑排序:POJ1094 * 串算法:POJ1035、POJ3080、POJ1936 * 哈希表和二分查找等高效查找法:POJ3349、POJ3274、POJ2151、POJ1840、POJ2002...
具体来说,这里可以采用Prim算法来构建最小生成树。Prim算法的基本思想是从一个顶点出发,逐步添加边到当前生成树中,直到包含所有的顶点。每次添加的边都是未被加入到树中的顶点到已有的树中的顶点之间的最短边。 ...
常见的求解最小生成树的算法有Prim算法和Kruskal算法。在这个问题中,由于需要先进行快速排序,Kruskal算法更为合适,因为它依赖于边的排序。Kruskal算法的基本步骤是: 1. 将所有边按权重从小到大排序。 2. 初始化...