http://tjuacm.chaosheng.top/problem.php?id=1290
https://vjudge.net/problem/POJ-2377

一开始就写好了,但是一直WA,是因为cost初始化不对,应该初始化为-INF,i==j时为0,并且有可能出现重复边,注意处理。
参考修改: https://www.cnblogs.com/wkfvawl/p/9246072.html

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1010;

int n, m, sum;
int vis[N];
int dis[N];
int cost[N][N];

void Prim(){ //从第一个点开始找周围最短的边 
    memset(dis, INF, sizeof(dis));
    for(int i = 1; i <= n; i++){
        dis[i] = cost[1][i];
        vis[i] = 0;
    }
    dis[1] = 0;
    vis[1] = 1;
    int i;
    for( i = 1; i < n; i++){ //寻找权值最小的点  
        int maxn = -INF, tmp;
        for(int j = 1; j <= n; j++){
            if(!vis[j] && dis[j] > maxn){
                maxn = dis[j];
                tmp = j;
            }
        }
        if(maxn == -INF){ //不连通
            sum = -1; 
            break;
        }
        sum += maxn;
        vis[tmp] = 1; //把点加入生成树;
        for(int j = 1; j <= n; j++){ //利用新点改变其他不在最小生成树中的点的边
            if(!vis[j] && dis[j] < cost[tmp][j]){
                dis[j] = cost[tmp][j]; //更新 
            }
        }
    }
}

int main(){
    while(cin >> n >> m){
        sum = 0;
        int a, b, c;
        //memset(cost, -INF, sizeof(cost));
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                if(i == j){
                    cost[i][j] = 0;
                }else{
                    cost[i][j] = -INF;
                }
            }
        }

        for(int i = 1; i <= m; i++){
            cin >> a >> b >> c;
            if(cost[a][b] < c){  //若出现重边记录最小长度 
                cost[a][b] = cost[b][a] = c;
            }
        } 
        Prim();
        printf("%d\n", sum);
    }
    return 0;
}