标签:iaccepted 并查集 最小生成树 hdu 1102
3 0 990 692 990 0 179 692 179 0 1 1 2
179
思路就是构造一棵最小生成树,所以将距离排序,从小到大依次并入,直到集合数为1为止。
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXX = 102;
typedef struct Road{
int x, y, dist;
Road(int ix, int iy, int idist){
x = ix;
y = iy;
dist = idist;
}
}road;
int n,roads,length;
vector<road> vec;
int pre[MAXX];
bool yes[MAXX][MAXX] = { 0 };
void init(int n){
for (int i = 1; i <= n; ++i){
pre[i] = i;
}
}
int root(int x){
if (x != pre[x]){
pre[x] = root(pre[x]);
}
return pre[x];
}
bool merge(int x, int y){
int fy = root(y);
int fx = root(x);
bool mark = false;
if (fx != fy){
pre[fx] = fy;
mark = true;
--roads;
}
return mark;
}
bool cmp(road a, road b){
return a.dist < b.dist;
}
int main(){
//freopen("in.txt", "r", stdin);
int dist, t, x, y;
while (scanf("%d", &n) != EOF){
roads = n - 1;
vec.clear();
memset(yes, 0, sizeof(yes));
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
scanf("%d", &dist);
if (i == j || i > j)continue;//重复的路径不进行添加
vec.push_back(road(i, j, dist));
}
}
sort(vec.begin(), vec.end(), cmp);
init(n);
scanf("%d", &t);
while (t--){
scanf("%d %d", &x, &y);
merge(x, y);
yes[x][y] = true;
}
length = 0;
vector<road>::iterator ite = vec.begin();
for (; ite != vec.end() && roads != 0; ++ite){
x = (*ite).x;
y = (*ite).y;
dist = (*ite).dist;
if (yes[x][y])continue;
if (merge(x, y))length += dist;
}
printf("%d\n", length);
}
return 0;
}
HDU 1102 Constructing Roads (裸的并查集),布布扣,bubuko.com
HDU 1102 Constructing Roads (裸的并查集)
标签:iaccepted 并查集 最小生成树 hdu 1102
原文地址:http://blog.csdn.net/iaccepted/article/details/29220347