题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz
输入输出格式
输入格式:第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
对于20%的数据:N<=5,M<=20
对于40%的数据:N<=50,M<=2500
对于70%的数据:N<=500,M<=10000
对于100%的数据:N<=5000,M<=200000
样例解释:
所以最小生成树的总边权为2+2+3=7
Prim算法模板:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=5005;
int n,m;
int lowCost[maxn];
int e[maxn][maxn];
long long ans=0;
void init(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) e[i][j]=0;
else e[i][j]=INF;
}
}
}
int FindMin(){
int k=0;
int minx=INF;
for(int i=1;i<=n;i++){
if(lowCost[i]&&lowCost[i]<minx){
minx=lowCost[i];
k=i;
}
}
return k;
}
int prim(){
for(int i=1;i<=n;i++){
lowCost[i]=e[1][i];
}
lowCost[1]=0;
for(int i=1;i<n;i++){
int k=FindMin();
if(k){
ans+=lowCost[k];
lowCost[k]=0;
for(int j=2;j<=n;j++){
if(lowCost[j]&&e[k][j]<lowCost[j]){
lowCost[j]=e[k][j];
}
}
}else return -1;
}
return ans;
}
int main(){
cin>>n>>m;
init();
while(m--){
int a,b,c;
cin>>a>>b>>c;
if(e[a][b]>c) e[a][b]=e[b][a]=c;
}
long long res=prim();
if(res==-1) printf("orz\n");
else printf("%lld\n",res);
return 0;
}