1593.并查集(一)
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
一个城市中有n个人,其中一些人是朋友关系,同时他们都认为:朋友的朋友是朋友,现在任给两个人,问他们是否是朋友关系。
输入
先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友关系,接下来的m行每行给出两个0~n-1之间的整数,表示这两个人是朋友关系。
最后一行再输入两个0~n-1之间的整数,问他们是否是朋友关系。
输出
是朋友关系则输出”Yes”,否则输出”No”。
#include <iostream>
using namespace std;
int a[1000]; //存储并查集
int n,m;
int fsearch(int x); //返回结点x的根节点
int main()
{
//输入数据
cin>>n>>m;
for(int i=0;i<n;i++)
{
a[i]=i; //初始时每个人只和自己做朋友
}
int x,y; //是朋友关系的两个人
int kx,ky; //根节点
for(int i=0;i<m;i++)
{
cin>>x>>y;
//cout<<x<<y;
kx=fsearch(x); //x的根节点
ky=fsearch(y); //y的根结点
a[ky]=kx; //相连
}
//输出数据
cin>>x>>y;
kx=fsearch(x); //x的根节点
ky=fsearch(y); //y的根结点
if(kx==ky)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
return 0;
}
int fsearch(int x)
{
int f=a[x];
while(f!=a[f]) //若未找到根节点
{
f=a[f]; //继续向上搜索
}
a[x]=f; //更新a[x]的值,使他离根节点更近,方便下一次搜索
return f;
}
1594.并查集(二)
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
一个城市中有一些犯罪团伙,共有n个人,有m条信息同伙信息,并且知道同伙的同伙是同伙,问共有多少个犯罪团伙。
输入
先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友关系,接下来的m行每行给出两个0~n-1之间的整数,表示这两个人是朋友关系。
输出
输出犯罪团伙的个数。
#include <iostream>
using namespace std;
int a[1000]; //存储并查集-犯罪团伙
int n,m;
int fsearch(int x); //返回x结点的根节点
int main()
{
cin>>n>>m;
for(int i=0; i<n; i++) //初始化并查集
{
a[i]=i;
}
int x,y;
int kx,ky;
for(int i=0; i<m; i++) //读入数据
{
cin>>x>>y;
kx=fsearch(x);
ky=fsearch(y);
a[ky]=kx;
}
int cnt=0; //犯罪团伙个数
for(int i=0; i<n; i++)
{
if(a[i]==i) //数根节点个数
{
cnt++;
}
}
cout<<cnt<<endl;
return 0;
}
int fsearch(int x) //返回x结点的根节点
{
int f=x;
while(f!=a[f])
{
f=a[f];
}
a[x]=f; //使x结点直接指向其根节点
return f;
}
1595.并查集(三)
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
一个城市中有n个人,其中一些人是朋友关系,一些人之间是敌人关系,同时他们都认为:朋友的朋友是朋友,敌人的敌人是朋友,(注意:朋友的敌人不一定是敌人),现在任给两个人,问他们是否是朋友关系。
输入
先输入两个正整数n和m(均小于1000),表示城市里有n个人,并且将给出m对朋友或敌人关系,接下来的m行每行三个整数,先给出一个整数0或1(0表示后面这两个人是朋友,1表示是敌人),再给出两个0~n-1之间的整数表示两个人。
最后一行再输入两个0~n-1之间的整数,问这两个人是否是朋友关系。
输出
是则输出”Yes”,否则输出”No”。
#include <iostream>
using namespace std;
int a[1000]; //朋友并查集
int b[1000][1000]; //存储敌人关系
int n,m;
int fa_search(int x); //返回并查集a里x的根节点
void fa_add(int x, int y); //将x和y添加成朋友关系
void fb_add(int x, int y); //将x和y添加成敌人关系
void f_add(int x, int y); //将y的敌人与x添加成朋友关系
//(敌人的敌人是朋友)
int main()
{
cin>>n>>m;
for(int i=0; i<n; i++) //初始化并查集
{
a[i]=i;
}
int p,x,y;
int kx,ky;
for(int i=0; i<m; i++) //输入数据
{
cin>>p>>x>>y;
if(p==0) //x和y是朋友
{
fa_add(x, y);
}
else //x和y是敌人
{
//在b中添加敌人关系
fb_add(x, y);
//y的所有敌人是x的朋友
f_add(x, y);
//x的所有敌人是y的朋友
f_add(y, x);
}
}
cin>>x>>y;
kx=fa_search(x);
ky=fa_search(y);
if(kx==ky) //输出数据
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
return 0;
}
int fa_search(int x) //返回并查集a里x的根节点
{
int f=a[x];
while(f!=a[f])
{
f=a[f];
}
a[x]=f; //更新a[x]
return f;
}
void fa_add(int x, int y) //将x和y添加成朋友关系
{
int kx,ky;
kx=fa_search(x);
ky=fa_search(y);
a[ky]=kx;
}
void fb_add(int x, int y) //将x和y添加成敌人关系
{
b[x][y]=1;
b[y][x]=1;
}
void f_add(int x, int y) //将y的敌人与x添加成朋友关系
{ //(敌人的敌人是朋友)
for(int i=0; i<n; i++)
{
if(i!=x&&i!=y)
{
if(b[y][i]==1) //若y和i是敌人关系
{
fa_add(x,i); //那么x和i是朋友关系
}
}
}
}
【后记】
1.并查集(四)吭哧半天没写出来,好气啊,待续