首页 > 代码库 > URAL - 1966 - Cycling Roads(并查集 + 判线段相交)
URAL - 1966 - Cycling Roads(并查集 + 判线段相交)
题意:n 个点,m 条边(1 ≤ m < n ≤ 200),问所有点是否连通(两条边相交,则该 4 点连通)。
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1966
——>>对于每条边,边上的两端点并入集合,枚举边与边,判断他们是否相交,是的话各点并入集合,最后看集合内元素的个数是否为n。。
#include <cstdio> #include <cmath> const int MAXN = 200 + 10; const double EPS = 1e-8; struct POINT { double x; double y; POINT(){} POINT(double x, double y) : x(x), y(y){} } p[MAXN]; int n, m; int fa[MAXN], cnt[MAXN]; int u[MAXN], v[MAXN]; typedef POINT Vector; Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); } int Dcmp(double x) { if (fabs(x) < EPS) return 0; return x > 0 ? 1 : -1; } double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; } double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; } bool SegmentProperIntersection(POINT a1, POINT a2, POINT b1, POINT b2) { double c1 = Cross(a2 - a1, b1 - a1); double c2 = Cross(a2 - a1, b2 - a1); double c3 = Cross(b2 - b1, a1 - b1); double c4 = Cross(b2 - b1, a2 - b1); return Dcmp(c1) * Dcmp(c2) < 0 && Dcmp(c3) * Dcmp(c4) < 0; } bool OnSegment(POINT p, POINT a1, POINT a2) { return Dcmp(Cross(a1 - p, a2 - p)) == 0 && Dcmp(Dot(a1 - p, a2 - p)) < 0; } void Init() { for (int i = 1; i <= n; ++i) { fa[i] = i; cnt[i] = 1; } } int Find(int x) { return x == fa[x] ? x : (fa[x] = Find(fa[x])); } void Union(int x, int y) { int xroot = Find(x); int yroot = Find(y); if (xroot != yroot) { fa[yroot] = xroot; cnt[xroot] += cnt[yroot]; } } void Read() { for (int i = 1; i <= n; ++i) { scanf("%lf%lf", &p[i].x, &p[i].y); } for (int i = 0; i < m; ++i) { scanf("%d%d", u + i, v + i); Union(u[i], v[i]); for (int j = 1; j <= n; ++j) { if (j != u[i] && j != v[i] && OnSegment(p[j], p[u[i]], p[v[i]])) { Union(j, u[i]); } } } } void Merge() { for (int i = 0; i < m; ++i) { for (int j = i + 1; j < m; ++j) { if (SegmentProperIntersection(p[u[i]], p[v[i]], p[u[j]], p[v[j]])) { Union(u[i], u[j]); } } } } void Output() { cnt[Find(1)] == n ? puts("YES") : puts("NO"); } int main() { while (scanf("%d%d", &n, &m) == 2) { Init(); Read(); Merge(); Output(); } return 0; }
URAL - 1966 - Cycling Roads(并查集 + 判线段相交)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。