思路:最先生成树+kruskal
分析:kruskal的模板题,最后只要加上一个判断是否所有的点的根节点都是一样的即可。
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; #define MAXN 1010 #define INF 0XFFFFFFF int n , m , ans; int father[MAXN]; int rank[MAXN]; struct Edge{ int x; int y; int value; }e[20010]; bool cmp(Edge e1 , Edge e2){ return e1.value > e2.value; } void init_Set(){ for(int i = 0 ; i <= n ; i++){ father[i] = i; rank[i] = 0; } } int find_Set(int x){ if(x != father[x]) father[x] = find_Set(father[x]); return father[x]; } void union_Set(int x , int y){ if(rank[x] > rank[y]) father[y] = x; else{ if(rank[x] == rank[y]) rank[y]++; father[x] = y; } } void kruskal(){ init_Set(); sort(e , e+m , cmp); ans = 0; for(int i = 0 ; i < m ; i++){ int root_x = find_Set(e[i].x); int root_y = find_Set(e[i].y); if(root_x != root_y){ union_Set(root_x , root_y); ans += e[i].value; } } int cnt = 0; int vis[20010]; memset(vis , 0 , sizeof(vis)); for(int i = 1 ; i <= n ; i++){ if(!vis[find_Set(i)]){ cnt++; vis[find_Set(i)] = 1; } } if(cnt == 1) printf("%d\n" , ans); else printf("-1\n"); } int main(){ scanf("%d%d" , &n , &m); for(int i = 0 ; i < m ; i++) scanf("%d%d%d" , &e[i].x , &e[i].y , &e[i].value); kruskal(); return 0; }