您的位置:首页 > 其它

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

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

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

收获:模板+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;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: