版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}