标签:open data- splay 一个 end 并查集 one show preview
给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。
求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。
给定一张边带权的无向图G=(V, E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。
由V中的全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一棵生成树,其中边的权值之和最小的生成树被称为无向图G的最小生成树。
第一行包含两个整数n和m。
接下来m行,每行包含三个整数u,v,w,表示点u和点v之间存在一条权值为w的边。
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。
1≤n≤1051≤n≤105,
1≤m≤2∗1051≤m≤2∗105,
图中涉及边的边权的绝对值均不超过1000。
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
6
################################################
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 1e5+10, M = 2*1e5+10, INF = 0x3f3f3f3f; 5 6 int fa[N]; 7 int n, m; 8 9 struct edge{ 10 int a, b, w; 11 bool operator < (const edge& t)const{ 12 return w < t.w; 13 } 14 }edges[M]; 15 16 int find(int x){ 17 if(x != fa[x]) fa[x] = find(fa[x]); 18 return fa[x]; 19 } 20 21 int kruskal(){ 22 int res = 0, cnt = 0;//res是权值和,cnt是边数和 23 sort(edges, edges+m);//1 排序 24 for(int i = 1;i <= n;++i)fa[i] = i;//初始化并查集 25 for(int i = 0;i < m;++i){//从小到大遍历每条边 26 int a = edges[i].a, b = edges[i].b, w = edges[i].w; 27 a = find(a), b = find(b); 28 if(a != b){//如果当前边的两个顶点不在一个集合,就合并 29 fa[a] = b; 30 res += w; 31 cnt++; 32 } 33 } 34 if(cnt < n-1) return INF; 35 else return res; 36 } 37 38 int main(){ 39 cin >> n >> m; 40 for(int i = 0;i < m;++i){ 41 int u, v, w; 42 cin >> u >> v >> w; 43 edges[i] = {u, v, w}; 44 } 45 int t = kruskal(); 46 if(t == INF)cout << "impossible" << endl; 47 else cout << t << endl; 48 return 0; 49 }
标签:open data- splay 一个 end 并查集 one show preview
原文地址:https://www.cnblogs.com/sxq-study/p/12238134.html