很典型的一道并查集,动态的判断距离足够近的点就归为一类。
#include <iostream> #include <vector> #include <cmath> using namespace std; class Node { public: Node() { x=y=0.0f; nodeID=-1; parent=NULL; rank=0; } Node(double xi,double yi,int id) { x=xi; y=yi; nodeID=id; parent=NULL; } Node(double xi,double yi) { x=xi; y=yi; parent=NULL; } double x,y; int nodeID; Node* parent; int rank; }; //并查集几个基本函数 void MakeSet(Node* node) { node->parent=node; node->rank=0; return; } Node* FindSet(Node* pNode) { if(pNode->parent!=pNode) { pNode->parent=FindSet(pNode->parent); } return pNode->parent; } void LinkSets(Node* pNode1,Node* pNode2) { if(pNode1->rank>pNode2->rank) { pNode2->parent=pNode1; } else if(pNode1->rank<pNode2->rank) { pNode1->parent=pNode2; } else { pNode1->parent=pNode2; pNode2->rank++; } return; } void UnionSets(Node *pNode1,Node *pNode2) { LinkSets(FindSet(pNode1),FindSet(pNode2)); return; } double Distance(Node node1,Node node2) { return sqrt( pow(node1.x-node2.x,2) + pow(node1.y-node2.y,2) ); } int main() { Node* allNodeVec[1002]; Node* repairedNodeVec[1002]; int n,d; scanf("%d%d",&n,&d); double xi,yi; for(int i=0;i<n;i++) { scanf("%lf%lf",&xi,&yi); allNodeVec[i]=new Node(xi,yi,i+1); MakeSet(allNodeVec[i]); } int iRepNum=0;//See how many computers have been repaired. char opera; while(scanf("%c",&opera)!=EOF) { if(opera=='O') { int newNodeId=-1; scanf("%d",&newNodeId); for(int i=0;i!=iRepNum;i++) { if(Distance(*allNodeVec[newNodeId-1],*repairedNodeVec[i])<= d) { if(FindSet(allNodeVec[newNodeId-1])!= FindSet(repairedNodeVec[i]) ) { UnionSets(allNodeVec[newNodeId-1],repairedNodeVec[i]); } } } repairedNodeVec[iRepNum]=allNodeVec[newNodeId-1]; iRepNum++; } else if(opera=='S') { int ai,bi; scanf("%d%d",&ai,&bi); if(FindSet(allNodeVec[ai-1]) == FindSet(allNodeVec[bi-1])) { printf("SUCCESS\n"); } else { printf("FAIL\n"); } } } }