hdu 1558 Segment set(并查集+线段相交)

来源:互联网 发布:淘宝店铺上新微淘描述 编辑:程序博客网 时间:2024/06/11 05:29

题目大意是依次给出线段,如果询问第k条给出的线段就输出与第k条线段直接相交和间接相交的所有线段条数(注意包含他本身,所以num初始化为1)


典型判断相交,用并查集


我的代码有个地方wa了我好久,就是在函数中,如果交换参数的值,注意参数如果是指针类型的,导致调用该函数的外部函数中的数据也交换了影响程序结果(看注释)

我的代码:

#include<stdio.h>#include<string.h>int father[1001];int num[1001];double line[1001][2][2];int n, q;double Min(double a, double b){return a < b ? a : b;}double Max(double a, double b){return a > b ? a : b;}bool equal(double a, double b){return a == b;}bool between(double a, double b, double c){if(a <= Max(b, c) && a >= Min(b, c))return 1;return 0;}int swap(double line1[][2], double line2[][2]){int i, j;double temp;for(i = 0; i < 2; i ++)for(j = 0; j < 2; j ++){temp = line1[i][j];line1[i][j] = line2[i][j];line2[i][j] = temp;}return 0;}bool cut(double line1[][2], double line2[][2])       //判断相交{double k1,k2, b1, b2, x, y;if(equal(line2[0][0], line2[1][0]))      //如果存在没有斜率的情况,就让函数进入下面的if语句中,但是这样交换却使全局line中的线段序号发生了变化{swap(line1, line2);              //所以我在main中对两个线段都进行了复制}if(equal(line1[0][0], line1[1][0]))   //没有斜率情况{if(equal(line2[0][0], line2[1][0])){if(equal(line1[0][0], line2[0][0]) && (between(line1[0][1], line2[0][1], line2[1][1]) || between(line1[1][1], line2[0][1], line2[1][1])|| between(line2[0][1], line1[0][1], line1[1][1]) || between(line2[1][1], line1[0][1], line1[1][1])))return 1;else{return 0;}}else{k2 = (line2[1][1] - line2[0][1]) / (line2[1][0] - line2[0][0]);b2 = line2[1][1] - k2 * line2[1][0];if(!between(line1[0][0], line2[0][0], line2[1][0]))return 0;y = k2 * line1[0][0] + b2;if(between(y, line1[0][1], line1[1][1]) && between(y, line2[0][1], line2[1][1]))return 1;elsereturn 0;}}k1 = (line1[1][1] - line1[0][1]) / (line1[1][0] - line1[0][0]);b1 = line1[1][1] - k1 * line1[1][0];k2 = (line2[1][1] - line2[0][1]) / (line2[1][0] - line2[0][0]);b2 = line2[1][1] - k2 * line2[1][0];if(k1 - k2 == 0 && (between(line1[0][0], line2[0][0], line2[1][0]) || between(line1[1][0], line2[0][0], line2[1][0])|| between(line2[0][0], line1[0][0], line1[1][0]) || between(line2[1][0], line1[0][0], line1[1][0])))return 1;x = (b2 - b1) / (k1 - k2);y = x * k1+ b1;if(between(y, line1[0][1], line1[1][1]) && between(y, line2[0][1], line2[1][1])&& between(x, line1[0][0], line1[1][0]) && between(x, line2[0][0], line2[1][0]))return 1;return 0; }int init(){int i;n = 0;for(i = 1; i <= 1000; i ++){father[i] = i;num[i] = 1;}return 0;}int find(int x){if(father[x] == x)return x;return father[x] = find(father[x]);}int uni(int a, int b){int afa = find(a), bfa = find(b);if(afa == bfa)return 0;num[afa] += num[bfa];father[bfa] = afa;return 0;}int copy(double line1[][2], double line2[][2]){int i, j;for(i = 0; i < 2; i ++)for(j = 0; j < 2; j ++){line1[i][j] = line2[i][j];}return 0;}int main(){int cases, i, k;char str[2];double temp1[2][2];double temp2[2][2];scanf("%d", &cases);while(cases --){scanf("%d", &q);init();while(q --){scanf("%s", str);if(str[0] == 'P'){n ++;scanf("%lf%lf%lf%lf", &line[n][0][0], &line[n][0][1], &line[n][1][0], &line[n][1][1]);for(i = 1; i < n; i ++){copy(temp1, line[n]);//进行复制,避免交换copy(temp2, line[i]);//进行复制,避免交换if(cut(temp1, temp2))uni(i, n);}}else{scanf("%d", &k);printf("%d\n", num[find(k)]);}}if(cases != 0)printf("\n");}return 0;}

以后一定要留个心眼,就是在函数对参数进行交换的时候

原创粉丝点击