题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz。
输入格式
第一行包含两个整数 N,M,表示该图共有 N 个结点和 M 条无向边。
接下来M行,每行依次给出三个整数,为起点、终点、距离
输出格式
如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz。
输入样例
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出样例
7
解法
代码
#include<iostream>
using namespace std;
int main(){
//n为顶点数,m为要输入边数 ,sum为树的权值
int n=0,m=0,sum=0,max=0x7fffffff;
//用邻接矩阵来存边的权值
int edge[5001][5001]={},set[5001]={0},dist[5001]={0x7fffffff};
//读取数据
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
edge[i][j]=max;
}
int tempi=0,tempj=0,tempdis=0;
for(int i=1;i<=m;i++){
cin >> tempi >> tempj >> tempdis;
if (edge[tempi][tempj] != 0 && edge[tempi][tempj] < tempdis)
continue;
edge[tempi][tempj] = tempdis;
edge[tempj][tempi] = tempdis;
}
//初始化prim算法
set[1]=1;
for(int i=1;i<=n;i++){
dist[i]=edge[1][i];
}
//prim
for(int i=2;i<=n;i++){
//选最近的点
int tempv=0,tempdist=max;
for(int j=1;j<=n;j++){
if(set[j]==0&&dist[j]<tempdist){
tempv=j;
tempdist=dist[j];
}
}
//将点加入树种
set[tempv]=1;
sum+=dist[tempv];
//刷新距离
for(int j=1;j<=n;j++){
if(set[j]==0&&edge[tempv][j]<dist[j])
dist[j]=edge[tempv][j];
}
}
bool all=true;
for(int i=1;i<=n;i++){
if(set[i]==0)
all=false;
}
if(all)
cout<<sum;
else cout<<"orz";
return 0;
}