Find them, Catch them POJ - 1703(并查集,模板)

    xiaoxiao2021-03-25  102

    题意:给一些木棍(两个端点)判断两个木棍是否连接(间接连接也可以,间接连结就是并查集好用)

    分析:判断线段相交的模板,和并查集基本应用。

    收获:模板+1;

    并查集的rank+1;

    从卢神的代码中学到了处理并查集find函数的正确操作

    以前都是

    int find_father(int x) { return x==father[x]?x:find_father(father[x]); }很简短,觉得自己很帅,其实不存在的。这要会浪费很多时间。

    正确的应该是:

    int find_father(int x) { if(father[x]==x) return x; return father[x]=find_father(father[x]); }这样在向上求父亲的时候会顺路把经过的点father[x]赋值

    #include <iostream> #include <algorithm> #include <cstdio> #include <string> using namespace std; int father[200]; void Init( ) { for(int i=0; i<=199; i++) { father[i]=i; } return; } int find_father(int x) { if(father[x]==x) return x; return father[x]=find_father(father[x]); } void Union(int a,int b) { a=find_father(a); b=find_father(b); father[b]=a; } //mo bannn const double eps=1e-10; struct point { double x, y; } sb[20],se[20]; double min(double a, double b) { return a < b ? a : b; } double max(double a, double b) { return a > b ? a : b; } bool inter(point a, point b, point c, point d) { if ( min(a.x, b.x) > max(c.x, d.x) || min(a.y, b.y) > max(c.y, d.y) || min(c.x, d.x) > max(a.x, b.x) || min(c.y, d.y) > max(a.y, b.y) ) return 0; double h, i, j, k; h = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); i = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x); j = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x); k = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x); return h * i <= eps && j * k <= eps; } //mo bannn int main () { int m; while(scanf("%d",&m)&&m) { for(int i=1; i<=m; i++) { scanf("%lf%lf%lf%lf",&sb[i].x,&sb[i].y,&se[i].x,&se[i].y); } Init(); for(int i=1; i<=m; i++) { for(int j=i+1; j<=m; j++) { if(inter(sb[i],se[i],sb[j],se[j])) { Union(i,j); } } } int a,b; while(scanf("%d%d",&a,&b)&&a&&b) { a=find_father(a); b=find_father(b); if(a==b) cout << "CONNECTED\n"; else cout << "NOT CONNECTED\n"; } } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-8397.html

    最新回复(0)