标签:
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