标签:
题意:
有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通)
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <map> #include <algorithm> #include <set> using namespace std; #define MM(a) memset(a,0,sizeof(a)) typedef long long ll; typedef unsigned long long ULL; const int mod = 1000000007; const double eps = 1e-10; const int inf = 0x3f3f3f3f; const int big=50000; int max(int a,int b) {return a>b?a:b;}; int min(int a,int b) {return a<b?a:b;}; int r[15]; struct node{ int x,y; }p; struct Line{ node a,b; }line[15]; int neiji(node a,node b) { return a.x*b.x+a.y*b.y; } int jian(node a,node b,node c) { return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } int findr(int i) { if(i!=r[i]) r[i]=findr(r[i]); return r[i]; } void unite(int i,int j) { int ri=findr(i),rj=findr(j); r[rj]=ri; } int solve(Line m,Line n) { if(min(m.a.x,m.b.x)<=max(n.a.x,n.b.x)&& max(m.a.x,m.b.x)>=min(n.a.x,n.b.x)&& min(m.a.y,m.b.y)<=max(n.a.y,n.b.y)&& max(m.a.y,m.b.y)>=min(n.a.y,n.b.y)&& jian(m.a,m.b,n.a)*jian(m.a,m.b,n.b)<=0&& jian(n.a,n.b,m.a)*jian(n.a,n.b,m.b)<=0) return 1; return 0; }//跨立实验判断线段相交 int main() { int n; while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) scanf("%d %d %d %d",&line[i].a.x,&line[i].a.y,&line[i].b.x,&line[i].b.y); for(int i=1;i<=n;i++) r[i]=i; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)/*并查集检验线段的连通性,注意是两层循环,每个i都将直接与其相连的加入它当前所在的集合*/ { if(findr(i)==findr(j))continue; if(solve(line[i],line[j])) unite(i,j); } while(1) { int a,b; scanf("%d %d",&a,&b); if(!a||!b) break; if(findr(a)==findr(b)) printf("CONNECTED\n"); else printf("NOT CONNECTED\n"); } } return 0; }
分析:跨立实验模板+并查集
标签:
原文地址:http://www.cnblogs.com/smilesundream/p/5209159.html