码迷,mamicode.com
首页 > 其他好文 > 详细

并查集朋友圈问题

时间:2017-11-27 23:43:57      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:int()   节点   nio   合并   遍历   ++   child   void   ios   

朋友的朋友是朋友,敌人的敌人是朋友

 

#include<iostream>
#include<iomanip>
using namespace std;

int r[1001][1001]={0};

class UnionSet
{
public:
UnionSet(int size):n(size),set(new int[size])
{
for(int i=0;i<size;i++)
set[i]=-1; //初始化为-1
}

//找到某个节点的根节点
int findRoot(int child)
{
if(set[child] < 0)
return child;
while(set[child]>0)
child = set[child];
return child;
}


//合并两个节点
void Union(int a , int b){
int x = findRoot(a);
int y = findRoot(b);
if(x == y)
return ; //a,b已经在一个集合中

set[x] = set[x] + set[y];
set[y] = x;
}


void print(){
int count = 0;

for(int i=0;i<n;i++)
{
if(set[i]<0)
count++;
}

cout<<"朋友圈个数为: "<<count<<endl;
}

public:
int *set;
int n;
};

int main(){

int n,m;
char c;
int x,y;
cin>>n>>m;
UnionSet set(n);


for(int i=1;i<=m;i++) //遍历m对关系,如果关系是敌人,则记录关系。如果是朋友,则合并
{
cin>>c>>x>>y;
if(c==‘E‘)
{
r[x][y] = 1;
r[y][x] = 1;
}
if(c == ‘F‘)
set.Union(x,y);
}


for(i=1;i<=n;i++){
for(int j=1;j<i;j++){
if(r[i][j]){  //若j是i的敌人
for(int k=1;k<i;k++){
set.Union(i,k);  //若k是j的敌人,那么k就是i的敌人的敌人,也就是朋友,将其合并
}
}
}
}

set.print();


return 0;


}

 

并查集朋友圈问题

标签:int()   节点   nio   合并   遍历   ++   child   void   ios   

原文地址:http://www.cnblogs.com/chenbo820/p/7906170.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!