HDU 3371 Kruskal

来源:互联网 发布:剪枝算法 编辑:程序博客网 时间:2024/06/07 02:08

这里边比较多,而且告诉了所需的边以及它们的权值,所以只要遍历edge,利用Kruskal算法

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define LLEN 25005int n, m, k;int map[505][505];int conn[505][505];typedef struct Edge{int u, v;int w;}Edge;Edge e[LLEN];int p[LLEN];int f[LLEN];bool cmp(Edge a, Edge b) {return a.w < b.w;}int find(int x) {return p[x] == x ? x : (p[x] = find(p[x]));}int kruskal(int n, int m) {int k = 1;int sum = 0;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {if(i == j) continue;if(p[j] == i) {k++;}}}sort(e, e+m, cmp);for(int i = 0; k < n && i < m; i++) {int x = find(e[i].u);int y = find(e[i].v);if(x != y) {sum += e[i].w;p[x] = y;k++;}}if(k < n) return -1;else return sum;}int main() {int file;scanf("%d", &file);while(file--) {scanf("%d%d%d", &n, &m, &k);for(int i = 0; i < m; i++) {scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);e[i].u--;e[i].v--;}for(int i = 0; i < n; i++) {p[i] = i;}for(int i = 0; i < k; i++) {int a;scanf("%d", &a);for(int j = 0; j < a; j++) {scanf("%d", &f[j]);f[j]--;}for(int j = 1; j < a; j++) {p[find(f[j])] = find(f[j-1]);}}int ans = kruskal(n, m);printf("%d\n", ans);}return 0;}


原创粉丝点击