poj2236并查集

来源:互联网 发布:张晓蓬 知乎 编辑:程序博客网 时间:2024/05/18 21:06

  很典型的一道并查集,动态的判断距离足够近的点就归为一类。

#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");}}}}


原创粉丝点击