您的位置:首页 > 其它

hdu 1875 畅通工程再续(图论:最小生成树)

2014-07-21 12:10 381 查看
简单图论题,就是在求最小生成树的基础上限定了边长度必须在10-1000之内才能连边

题目中用sqrt()没强制转换参数为double类型跪了2次

把题目要求看成了边长度必须在10-100内跪了1次...

代码如下:

<span style="font-size:18px;">#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 10010
#define LL long long
using namespace std;

int c, cnt;
int u[MAXN], v[MAXN], r[MAXN], p[MAXN];
double ans, w[MAXN];

struct Point {
int x, y;
}a[MAXN];

int find(int x) {
return x==p[x] ? x : p[x] = find(p[x]);
}

double get_dis(int i, int j) {
return sqrt(pow(1.0*(a[i].x-a[j].x), 2.0) + pow(1.0*(a[i].y-a[j].y), 2.0));
}

int cmp(int i, int j) {
return w[i]<w[j];
}

bool judge() {//判断能否建成最小生成树
int i, cnts = 0;
for(i=0; i<c; ++i)
if(p[i] == i)
cnts++;
if(cnts == 1)
return true;
return false;
}

bool Kruskal() {
int i, j, e, x, y;
ans = 0.0;
for(i=0; i<c; ++i)
p[i] = i;
for(i=0; i<cnt; ++i)
r[i] = i;
sort(r, r+cnt, cmp);
for(i=0; i<cnt; ++i) {
e = r[i];
x = find(u[e]);
y = find(v[e]);
if(w[e]>=10.0&&w[e]<=1000.0 && x != y) {
p[x] = y;
ans += w[e];
}
}
return judge();
}

int main(void) {
int T, i, j;
scanf("%d", &T);
while(T--) {
scanf("%d", &c);
for(i=0; i<c; ++i) {
scanf("%d%d", &a[i].x, &a[i].y);
}
cnt = 0;
for(i=0; i<c; ++i) {
for(j=i+1; j<c; ++j) {
u[cnt] = i;
v[cnt] = j;
w[cnt] = get_dis(i, j);
cnt++;
}
}
if(Kruskal())
printf("%.1f\n", ans*100);
else cout << "oh!" << endl;
}
return 0;
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: