【kuangbin並查集】+暴力合併

Wireless Network(poj2232)

vj題目地址
在這裏插入圖片描述
在這裏插入圖片描述

題意:

  1. 本題是每次增加一個點(一臺機器)。當兩個點距離小於d就連通。
  2. 之後會有詢問(強制在線)

做法

  1. 添加點時,枚舉其他已添加的點,計算是否連通。
  2. 詢問點時,看這兩個點是否在一個連通快裏。

反思

  1. 本題由於是算距離,要用距離公式,但比較時要用double比較,會有浮點誤差,1e-6.
  2. 由於數據量不大,所以能用乘法便用乘法。

AC

#include <iostream>
#include <cmath>
#include <cstdio>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
const int maxn=1000+10;
//double dis[maxn][maxn];
int dis[maxn][maxn];
int f[maxn],vis[maxn];
struct point
{
    int x,y;
}p[maxn];
int get_dis(point a, point b)
{
   // double dis=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
   int dis=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    //return sqrt(dis);
    return dis;
}
int find(int x)
{
    if(x==f[x])return x;
    return f[x]=find(f[x]);
}
void merge(int a,int b)
{
    int A=find(a);
    int B=find(b);
    if(A!=B)f[B]=A;
}
int main()
{
    int n,d;
    //double d;
    scanf("%d%d", &n, &d);
    For(i,1,n)f[i]=i,vis[i]=0;
    For(i,1,n)scanf("%d%d", &p[i].x,&p[i].y);
    For(i,1,n)
    {
        For(j,1,n)
        {
            dis[i][j]=dis[j][i]=get_dis(p[i],p[j]);
        }
    }
    char op[100];
    while(scanf("%s", op)!=EOF)
    {
        int p,q;
        if(op[0]=='O')
        {
            scanf("%d", &p);
            if(vis[p])continue;
            vis[p]=1;
            For(i,1,n)
            {
                if(i==p)continue;
                if(dis[i][p]<=d*d&&vis[i])merge(i,p);
                //if(dis[i][p]-d<=1e-6&&vis[i])merge(i,p);
            }
        }
        else
        {
            scanf("%d%d", &p,&q);
            int A=find(p),B=find(q);
            if(A!=B)printf("FAIL\n");
            else if(A==B)printf("SUCCESS\n");
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章