基准时间限制:1 秒 空间限制:131072 KB 分值: 0
难度:基础题
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 8 8
Output示例
37
具体过程就不多说,这是一个按点集求最小生成树的算法。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MaxInt 0x3f3f3f3f
typedef long long ll;
int map[1001][1001]; //邻接矩阵
int low[1001]; //记录2个点间最小权值
int vis[1001]; //标记某点是否已访问
int n,m; //点的数量
ll prim(){
int i,j,pos,min;
ll result=0;
memset(vis,0,sizeof(vis)); //标记所有点没有被访问
vis[1]=1;pos=1; //从某点开始,分别标记和记录该点
for(i=1;i<=n;i++)
if(i!=pos)
low[i]=map[pos][i]; //第一次给low数组赋值
//运行n-1次,找出最小权值并记录位置
for(i=1;i<n;i++){
min=MaxInt;
for(j=1;j<=n;j++)
if(vis[j]==0&&min>low[j]){
min=low[j];
pos=j;
}
if(MaxInt==min)
return -1; //不连通
result=result+min; //最小权相加
vis[pos]=1; //标记该点
//更新权值
for(j=1;j<=n;j++)
if(vis[j]==0&&low[j]>map[pos][j])
low[j]=map[pos][j];
}
return result;
}
int main(){
int i,j;
while(scanf("%d %d",&n,&m)!=EOF){
int x,y,w;
memset(map,MaxInt,sizeof(map)); //首先记录所有边的权为最大值
for(i=1;i<=m;i++){
scanf("%d %d %d",&x,&y,&w);
map[x][y]=map[y][x]=w;
}
ll s=prim();
printf("%lld\n",s);
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
int n = input.nextInt();
int m = input.nextInt();
int[][] map = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
map[i][j] = Integer.MAX_VALUE;
}
}
for (int i = 0; i < m; i++) {
int s = input.nextInt();
int e = input.nextInt();
int v = input.nextInt();
map[s][e] = v;
map[e][s] = v;
}
long res = prim(map);
System.out.println(res);
}
input.close();
}
public static long prim(int[][] map) {
long res = 0;
int len = map.length;
int[] vis = new int[len];
int[] low = new int[len];
int currNode = 1;
vis[1] = 1;
int[] path = new int[len]; // 存入path[i] 点到 i点此时距离最短
for (int i = 1; i < len; i++) {
low[i] = map[currNode][i];
path[i] = 1;
}
for (int i = 1; i < len - 1; i++) {
int min = Integer.MAX_VALUE;
for (int j = 1; j < len; j++) {
if (vis[j] == 0 && min > low[j]) {
min = low[j];
currNode = j;
}
}
if (min == Integer.MAX_VALUE)
return -1; // 不连通
res += min;
vis[currNode] = 1;
//System.out.println(path[currNode] + "---->" + currNode + " == " + min);
for (int j = 1; j < len; j++) {
if (vis[j] == 0 && low[j] > map[currNode][j]) {
low[j] = map[currNode][j];
path[j]=currNode;
}
}
}
return res;
}
public static void print(int[] res) {
for (int i = 1; i < res.length; i++) {
System.out.print(res[i] + " ");
}
System.out.println();
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
int n = input.nextInt();
int m = input.nextInt();
List<Node> list = new ArrayList<>();
for (int i = 0; i < m; i++) {
int s = input.nextInt();
int e = input.nextInt();
int v = input.nextInt();
Node node = new Node(s-1, e-1, v);
list.add(node);
}
Collections.sort(list, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.v - o2.v;
}
});
//print(list);
int[] pre = new int[n];
for (int i = 0; i < n; i++) {
pre[i] = i;
}
long res = kruskal(list,pre);
System.out.println(res);
}
input.close();
}
private static long kruskal(List<Node> list,int[] pre) {
long res = 0;
for(int i = 0;i<list.size();i++){
int fx = find(pre, list.get(i).s);
int fy = find(pre, list.get(i).e);
if(fx != fy){
res += list.get(i).v;
pre[fx] = fy;
//System.out.println((list.get(i).s + 1) +"---->" +(list.get(i).e + 1) + " == " + list.get(i).v);
}
}
return res;
}
public static int find(int[] pre, int x) {
int r = x;
while (pre[r] != r) {
r = pre[r];
}
// 路径压缩
int i = x;
int j;
while (i != r) {
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
public static void join(int[] pre, int x, int y){
int fx = find(pre, x);
int fy = find(pre, y);
if(fx != fy){
pre[fx] = fy;
}
}
public static void print(List<Node> list){
for (Node node : list) {
System.out.println(node.s + " -- > " +node.e + " == " + node.v);
}
}
}
class Node{
public int s;
public int e;
public int v;
public Node(int s, int e, int v) {
super();
this.s = s;
this.e = e;
this.v = v;
}
}