题目描述
如题,给出一个无向图,求出最小生成树。
输入输出格式
输入格式:第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=100000,M<=200000)
接下来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
说明
时空限制:1000ms,128M
数据规模:对于100%的数据:N<=100000,M<=200000
样例解释:最小生成树的总边权为2+2+3=7
#include<iostream>
#include<queue>
#define ll long long
using namespace std;
struct XY{ll to,pre,w;}e[500000];
struct cmp1{
bool operator ()(XY &a,XY &b){
return a.w>b.w;
}
};
ll n,m,ans=0,xx,yy,zz,sz=0,cnt=0;
ll las[100010];
bool flag[100010];
priority_queue<XY,vector<XY>,cmp1> Q;
void add(ll a,ll b,ll c){
++sz;e[sz].w=c;e[sz].to=b;e[sz].pre=las[a];las[a]=sz;
++sz;e[sz].w=c;e[sz].to=a;e[sz].pre=las[b];las[b]=sz;
}
int main(){
cin >>n>>m;
for (ll i=1;i<=m;++i){cin >>xx>>yy>>zz;add(xx,yy,zz);}
flag[1]=true;
for (ll i=las[1];i;i=e[i].pre) Q.push(e[i]);
while (!Q.empty()&&cnt<n-1){
ll mini=1e16;XY u;
u=Q.top();Q.pop();
if (flag[u.to]) continue;
flag[u.to]=true;++cnt;ans+=u.w;
for (ll j=las[u.to];j;j=e[j].pre)
if (!flag[e[j].to]) Q.push(e[j]);
}
cout <<ans<<endl;
return 0;
}