hdu1875 畅通工程再续(kruscal && 并查集)

来源:互联网 发布:盗号用什么软件最好 编辑:程序博客网 时间:2024/06/07 06:14

昨天下午做到现在,差点做吐。。。

本题需要注意,C == 0、1的特殊情况,中间算边长度时用int,最后用double转化(否则超时),再次中间变量的值要细心,否则弄错。

不过最坑的还是,我在边转化成int后,范围忘了改变。。。结果还以为别的地方出了问题,贡献N WA。。。。。

#include <stdio.h>#include <math.h>#include <stdlib.h>#include <algorithm>using namespace std;const int N = 5005;int pre0[N];int num;double sum;struct edges{    int pre;    int suc;    int wei;}edge[N];struct point{    int x;    int y;}poi[101];int cmp(edges x, edges y){    return (x.wei < y.wei) ? 1 : 0;}void init(int vs){    for(int i = 1; i <= vs; i ++)        pre0[i] = i;}int findd(int x){    int r = x;    while(r != pre0[r])        r = pre0[r];    return r;}void Union(int x, int y, int z){    int f1, f2;    f1 = findd(x);    f2 = findd(y);//    printf("fuck\n");    if(f1 != f2)    {        pre0[f2] = f1;        num ++;        sum += sqrt(z);    }}double kruskal(int es, int vs){    num = 1;    sum = 0;    init(vs);    sort(edge, edge + es, cmp);    for(int i = 1; i < es; i ++)        Union(edge[i].pre, edge[i].suc, edge[i].wei);  //  printf("%d %d %d %lf ", num, vs, es, sum);    if(num == vs) return sum;    else return -1;}int main(){  //  freopen("in.txt", "r", stdin);    int T, C, m;    __int64 w;    double ans;    scanf("%d", &T);    while(T --)    {        scanf("%d", &C);        for(int i = 1; i <= C; i ++)            scanf("%d%d", &poi[i].x, &poi[i].y);        if(C == 0 || C == 1) { printf("0.0\n"); continue; }        int num0 = 1;        for(int i = 1; i <= C - 1; i ++)            for(int j = i + 1; j <= C; j ++)            {                w = (poi[j].x - poi[i].x) * (poi[j].x - poi[i].x) + (poi[j].y - poi[i].y) * (poi[j].y - poi[i].y); //               printf("%d\n", w);                if(w >= 100 && w <= 1000000)                {                    edge[num0].pre = i;                    edge[num0].suc = j;                    edge[num0].wei = w; //                   printf("%lf\n", edge[num0].wei);                    num0 ++;                }            }        ans = kruskal(num0, C);        if(ans < 0) printf("oh!\n");        else printf("%.1lf\n", ans * 100);    }    return 0;}


0 0
原创粉丝点击