题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz
。
输入格式
第一行包含两个整数 N,M,表示该图共有 N 个结点和 M 条无向边。
接下来 M 行每行包含三个整数Xi,Yi,Zi,表示有一条长度为Zi 的无向边连接结点 Xi,Yi。
输出格式
如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz
。
输入输出样例
输入 #1
4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3
输出 #1
7
说明/提示
数据规模:
对于 20%20% 的数据,N≤5,M≤20。
对于 40%40% 的数据,N≤50,M≤2500。
对于 70%70% 的数据,N≤500,M≤104。
对于 100%100% 的数据:1≤N≤5000,1≤M≤2×105,1≤Zi≤104。
样例解释:
所以最小生成树的总边权为 2+2+3=7。
代码如下:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
vector<vector<int> >G(n+1);
vector<vector<int> >val(n+1);
for(int i=0;i<m;i++){
int u,v,w;
cin>>u>>v>>w;
G[u].push_back(v);
G[v].push_back(u);
val[u].push_back(w);
val[v].push_back(w);
}
int res=0;
vector<bool> visit(n+1);
visit[1]=1;
priority_queue<pair<int,int>,vector<pii>,greater<pii> > pq;
pq.push({0,1});
while(!pq.empty()){
pii p=pq.top();
pq.pop();
if(visit[p.se]) continue;
visit[p.se]=1;
res+=p.fi;
for(int i=0;i<G[p.se].size();i++){
pq.push({val[p.se][i],G[p.se][i]});
}
}
for(int i=1;i<=n;i++){
if(!visit[i]){
cout<<"orz"<<endl;
return 0;
}
}
cout<<res<<endl;
return 0;
}