9.27—并查集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengchencheng/article/details/82869827

1.并查集(一)

描述:一个城市中有n个人,其中一些人是朋友关系,同时他们都认为:朋友的朋友是朋友,现在任给两个人,问他们是否是朋友关系。

输入:先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友关系,接下来的m行每行给出两个0~n-1之间的整数,表示这两个人是朋友关系。最后一行再输入两个0~n-1之间的整数,问他们是否是朋友关系。

输出:是朋友关系则输出"Yes",否则输出"No"。

输入样例

8 5
0 3
5 1
3 7
3 7
3 4
7 6

输出样例

No

#include<iostream>
using namespace std;

void init();
int find(int t);
void funion(int tx, int ty);

int n, m;
int p[1005];
int x, y;

int main(){
	init();
	if(find(x) == find(y)){
	    cout << "Yes" <<endl;
	}
	else{
	    cout << "No" << endl;
	}
}

void init(){
	int u, v;
    cin >> n >> m;
	for(int i = 0; i < n; i++){
	    p[i] = i;
	}
	for(int i = 0; i < m; i++){
	    cin >> u >> v;
		funion(u, v);
	}
	cin >> x >> y;
}

void funion(int tx, int ty){//合并两个集合 
	int f1, f2;
	f1 = find(tx);
	f2 = find(ty);
	p[f1] = p[f2];
}

int find(int t){   //找到父结点 
    int h;
	h = t;
	while(h != p[h]){
	    h = p[h];
	}
	p[t] = h;
	return h;
}

2.并查集(二)

描述:一个城市中有一些犯罪团伙,共有n个人,有m条信息同伙信息,并且知道同伙的同伙是同伙,问共有多少个犯罪团伙。

输入:先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友关系,接下来的m行每行给出两个0~n-1之间的整数,表示这两个人是朋友关系。

输出:输出犯罪团伙的个数。

输入样例

6 4
0 1
1 2
2 0
0 4

输出样例

3

#include<iostream>
using namespace std;

void init();
int find(int t);
void funion(int tx, int ty);

int n, m;
int p[1005];

int main(){
	int cnt = 0; 
	init();
	for(int i = 0; i < n; i++){
		if(p[i] == i){
			cnt++;
		}
	}
	cout << cnt << endl;
}

void init(){
	int u, v;
    cin >> n >> m;
	for(int i = 0; i < n; i++){
	    p[i] = i;
	}
	for(int i = 0; i < m; i++){
	    cin >> u >> v;
		funion(u, v);
	}
}

void funion(int tx, int ty){//合并两个集合 
	int f1, f2;
	f1 = find(tx);
	f2 = find(ty);
	p[f1] = p[f2];
}

int find(int t){   //找到父结点 
    int h;
	h = t;
	while(h != p[h]){
	    h = p[h];
	}
	p[t] = h;
	return h;
}

3.并查集(三)

描述:一个城市中有n个人,其中一些人是朋友关系,一些人之间是敌人关系,同时他们都认为:朋友的朋友是朋友,敌人的敌人是朋友,(注意:朋友的敌人不一定是敌人),现在任给两个人,问他们是否是朋友关系。

输入:先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友或敌人关系,接下来的m行每行三个整数,先给出一个整数0或1(0表示后面这两个人是朋友,1表示是敌人),再给出两个0~n-1之间的整数表示两个人。最后一行再输入两个0~n-1之间的整数,问这两个人是否是朋友关系。

输出:是则输出"Yes",否则输出"No"。

输入样例

8 5
0 0 3
0 5 1
0 3 7
1 3 6
1 3 2
6 2

输出样例

Yes

#include<iostream>
using namespace std;

void init();
int find(int t);
void funion(int tx, int ty);

int n, m;
int x, y;
int p[1005], d[1005];

int main(){
	int cnt = 0; 
	init();
	if(find(x) == find(y)){
		cout << "Yes" << endl;
	}
	else{
		cout << "No" << endl;
	}
}

void init(){
	int s,u, v;
    cin >> n >> m;
	for(int i = 0; i < n; i++){
	    p[i] = i;
	    d[i] = i;
	}
	for(int i = 0; i < m; i++){
	    cin >> s >> u >> v;
	    if(s == 0){ //若是朋友,合并
	    	funion(u, v);
	    }
		else{
			if(d[u] == u && d[v] == v){  //若均无敌人,敌人即为彼此
				d[u] = v;
				d[v] = u;
			}
			else if(d[u] != u){   //若u由敌人,u的敌人就是v的朋友
				funion(find(v), d[u]);
			}
			else if(d[v] != v){   //若v有敌人,v的敌人就是u的朋友
				funion(find(u), d[v]);
			}
		}
	}
	cin >> x >> y;
}

void funion(int tx, int ty){//合并两个集合 
	int f1, f2;
	f1 = find(tx);
	f2 = find(ty);
	p[f1] = p[f2];
}

int find(int t){   //找到父结点 
    int h;
	h = t;
	while(h != p[h]){
	    h = p[h];
	}
	p[t] = h;
	return h;
}

4.并查集(四)

描述:一个城市中有n个人,其中一些人是朋友关系,一些人之间是敌人关系,同时他们都认为:朋友的朋友是朋友,敌人的敌人是朋友,朋友的敌人是敌人,现在任给两个人,问他们是否是朋友关系。

输入:先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友或敌人关系,接下来的m行每行三个整数,先给出一个整数0或1(0表示后面这两个人是朋友,1表示是敌人),再给出两个0~n-1之间的整数表示两个人。
最后一行再输入两个0~n-1之间的整数,问这两个人是否是朋友关系。

输出:是则输出"Yes",否则输出"No"。

输入样例

8 5
0 0 3
0 5 1
0 3 7
1 3 6
1 3 2
6 2

输出样例

Yes

#include<iostream>
using namespace std;
 
void init();
int find(int t);
void funion(int tx, int ty);
 
int n, m;
int x, y;
int p[1005], d[1005];
 
int main(){
	int cnt = 0; 
	init();
	if(find(x) == find(y) || d[x] == d[y]){
		cout << "Yes" << endl;
	}
	else{
		cout << "No" << endl;
	}
}
 
void init(){
	int s,u, v;
    cin >> n >> m;
	for(int i = 0; i < n; i++){
	    p[i] = i;
	    d[i] = i;
	}
	for(int i = 0; i < m; i++){
	    cin >> s >> u >> v;
	    if(s == 0){ //若是朋友,合并
	    	funion(u, v);
	    }
		else{
			if(d[u] == u && d[v] == v){  //若均无敌人,敌人即为彼此
				d[find(u)] = v;
				d[find(v)] = u;
			}
			else if(d[find(u)] != u){   //若u有敌人,u的敌人就是v的朋友
				funion(find(v), d[find(u)]);
			}
			else if(d[find(v)] != v){   //若v有敌人,v的敌人就是u的朋友
				funion(find(u), d[find(v)]);
			}
		}
	}
	cin >> x >> y;
}
 
void funion(int tx, int ty){//合并两个集合 
	int f1, f2;
	f1 = find(tx);
	f2 = find(ty);
	p[f1] = p[f2];
}
 
int find(int t){   //找到父结点 
    int h;
	h = t;
	while(h != p[h]){
	    h = p[h];
	}
	p[t] = h;
	return h;
}

猜你喜欢

转载自blog.csdn.net/chengchencheng/article/details/82869827