HDU 1875 畅通工程再续

来源:互联网 发布:淘宝mg小象 编辑:程序博客网 时间:2024/05/29 17:58

最后需要判断一下图是否所有顶点都联通。用并查集。全部连通之后必然只有一个i(i 属于n) 满足(find(i) == i) 他就是根。如果出现多个那么图不连通

/*********************************************** * Author: fisty * Created Time: 2015/2/28 14:36:42 * File Name   : N.cpp *********************************************** */#include <iostream>#include <cstring>#include <deque>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <bitset>#include <algorithm>using namespace std;#define Debug(x) cout << #x << " " << x <<endl#define Memset(x, a) memset(x, a, sizeof(x))const int INF = 0x3f3f3f3f;typedef long long LL;typedef pair<int, int> P;#define FOR(i, a, b) for(int i = a;i < b; i++)#define MAX_N 10010int n;int cnt;struct edge{    int u;    int v;    double cost;}G[MAX_N];void addedge(int u, int v, double cost){    G[cnt].u = u;    G[cnt].v = v;    G[cnt].cost = cost;    cnt++;}bool cmp(edge e1, edge e2){    return e1.cost < e2.cost;}int par[MAX_N];void init(){    for(int i = 0;i <= n; i++){        par[i] = i;    }}int find(int x){    if(x == par[x]) return x;    return par[x] = find(par[x]);}void unio(int x, int y){    x = find(x);    y = find(y);    if(x != y){        par[x] = y;    }}double kurskal(){    sort(G, G + cnt, cmp);    double ans = 0;    init();    for(int i = 0;i < cnt; i++){        edge e = G[i];        if(find(e.u) != find(e.v)){            unio(e.u, e.v);            ans += e.cost;        }    }    return ans;}struct node{    int x;    int y;}p[MAX_N];int dist(node a, node b){    return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);}int main() {    //freopen("in.cpp", "r", stdin);    cin.tie(0);    ios::sync_with_stdio(false);    int t;    scanf("%d", &t);    while(t--){        cnt = 0;        Memset(G, 0);        Memset(p, 0);        scanf("%d", &n);        FOR(i, 1, n+1){            scanf("%d%d", &p[i].x, &p[i].y);        }        FOR(i, 1, n+1){            FOR(j, i+1, n+1){                int d = dist(p[i], p[j]);                if(d <= 1000*1000 && d >= 100){                    addedge(i, j, (double)sqrt(d)*100.0);                   }            }        }        double ans = kurskal();        int ok = 0;        FOR(i, 1, n+1){            if(find(i) == i)                ok++;        }        if(ok == 1)            printf("%.1lf\n", ans);        else            printf("oh!\n");    }    return 0;}


0 0
原创粉丝点击