POJ2236 Wireless Network(并查集)

来源:互联网 发布:淘宝卖家何时收到货款 编辑:程序博客网 时间:2024/06/04 18:12

这个题并不难,就是并查集的运用,下面的程序是正确的~

但是里面的红色代码部分应该可以用break来进行优化剪枝的,这样运行时间会短一些,但是不知为什么如果加上break运行结果就不对了的,如果有哪位高手知道了的话请告诉我一下哟~先谢谢喽O(∩_∩)O~

 

 

#include<iostream>
using namespace std;
const int Max = 1005;

struct data
{
    int x, y, pa;
    bool flag;    //flag标记电脑是否修好
}com[Max];
int n, d;

void make_set()   //初始化
{
    for(int x = 1; x <= n; x ++)
  {
        com[x].pa = x;
        com[x].flag = false;
    }
}

int find_set(int x)   //找最终根节点
{
    if(x != com[x].pa)
        com[x].pa = find_set(com[x].pa);
    return com[x].pa;
}

void union_set(int x, int y)
{   

    x = find_set(x);
    y = find_set(y);
    if(x == y)
   return;
    com[y].pa = x;
}

bool dir(int x, int y)   //判断两修好的电脑是不是在距离之内
{   
    float a = com[x].x - com[y].x;
    float b = com[x].y - com[y].y;
    if(a * a + b * b <= d * d)
   return true;
    else
   return false;
}

int main(){
    int x, y;
    char str[10];
    scanf("%d %d", &n, &d);
    for(x = 1; x <= n; x ++)
        scanf("%d %d", &com[x].x, &com[x].y);
    getchar();
    make_set();     //要记得初始化
    while(scanf("%s", str) != EOF)  //学习这种新的输入格式
  {   
        if(str[0] == 'O')
    { 
            scanf("%d", &x);
            com[x].flag = true;  //标记该电脑为已维修过
            for(y = 1; y <= n; y ++)
                if(com[y].flag && dir(x, y))
                    {union_set(x, y); /*break;*/} //为什么这边不能加break剪枝呢??????????
        }
        else
    {  
            scanf("%d %d", &x, &y);
            if(com[x].flag && com[y].flag && find_set(x) == find_set(y))
                printf("SUCCESS/n");
            else
                printf("FAIL/n");
        }
    }
    return 0;
}

原创粉丝点击