标签:
1 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 1 3 3 4 5 6
1
题意:大约就是给出了连通的和不连通的岛屿 不连通的给出了 维修所需的价格 最后求用最小的代价 得到所有的连通
题解:比较简单的最小生成树的问题 Prim和Kruskal都可以 但是Kruskal用C++提交会超时 应该是自己剪枝不够 Prime跑了500+ms 感觉还好吧 后面总结两种算法的时候我会专门提到两种方法的选择问题 先给出两种方法的AC代码
//看HDU上面大牛的耗时都是200-ms 可惜不清楚是怎么实现的
Kruskal:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 511; int pi[maxn]; struct node{ int p, q, c; }no[maxn*maxn]; bool cmp(node a, node b); int Find(int x); int main(){ int cas; scanf("%d", &cas); while(cas--){ for(int i = 1; i <= 500; ++i){ pi[i] = i; } int n, m, k; scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= m; ++i){ scanf("%d%d%d", &no[i].p, &no[i].q, &no[i].c); } sort(no+1, no+m+1, cmp); int num = 0; int t, root, tmp; for(int i = 0; i < k; ++i){ scanf("%d%d", &t, &root); for(int j = 1; j < t; ++j){ scanf("%d", &tmp); int x = Find(tmp); int y = Find(root); if(x != y){ pi[x] = y; ++num; } } } if(num == n-1){ printf("0\n"); continue; } //bool flag = false; int ans = 0; for(int i = 1; i <= m; ++i){ int x = Find(no[i].p); int y = Find(no[i].q); if(x == y){ continue; } pi[x] = y; ans += no[i].c; ++num; if(num == n-1){ //flag = true; break; } } if(num == n-1){ printf("%d\n", ans); } else{ printf("-1\n"); } } return 0; } bool cmp(node a, node b){ return a.c < b.c; } int Find(int x){ int r=x; while(pi[r]!=r) r=pi[r]; return r; }
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 511; const int inf = 0x7ffffff; int dist[maxn][maxn]; int low[maxn]; bool vis[maxn]; int v[maxn]; void Prim(int n); int main(){ int cas; scanf("%d", &cas); while(cas--){ int n, m, k; scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j){ if(i == j){ dist[i][j] = 0; } else{ dist[i][j] = inf; } } } while(m--){ int p, q, c; scanf("%d%d%d", &p, &q, &c); dist[p][q] = dist[q][p] = min(dist[p][q], c); } while(k--){ int t; scanf("%d", &t); for(int i = 0; i < t; ++i){ scanf("%d", &v[i]); } for(int i = 0; i < t; ++i){ for(int j = 0; j < t; ++j){ dist[v[i]][v[j]] = 0; } } } Prim(n); } return 0; } void Prim(int n){ int ans = 0; for(int i = 1; i <= n; ++i){ low[i] = dist[1][i]; vis[i] = false; } vis[1] = true; int flag; for(int i = 2; i <= n; ++i){ int mi = inf; flag = -1; for(int j = 2; j <= n; ++j){ if(mi > low[j] && !vis[j]){ mi = low[j]; flag = j; } } if(mi >= inf){ flag = -1; break; } ans += mi; vis[flag] = true; for(int j = 2; j <= n; ++j){ if(dist[flag][j] < low[j] && !vis[j]){ low[j] = dist[flag][j]; } } } if(flag == -1){ printf("-1\n"); } else{ printf("%d\n", ans); } }
标签:
原文地址:http://blog.csdn.net/u012431590/article/details/46053311