并查集/图的划分
2016-04-25 13:39
225 查看
某个国家上有N个小岛组成,经过多年的基础设施积累,若干小岛之间建立了桥梁。现做行政区重新划分,规定只要有桥梁相连的的岛屿划为一个城市。问该国一共有多少城市?
该问题可以并查集来解决
#include<iostream>
using namespace std;
class CUnionFindSet
{
private:
int mn_N; //数目
int *m_pParent; //只有一个父结点。
public:
CUnionFindSet(int n);
~CUnionFindSet();
void Union(int i, int j); //求并
int Find(int i); //查根
void Print() const;
};
CUnionFindSet::CUnionFindSet( int n) //构造函数
{
mn_N=n;
m_pParent=new int[mn_N];
for(int i=0; i<mn_N; i++)
m_pParent[i]=i;
}
CUnionFindSet::~CUnionFindSet()//析构函数
{
if(m_pParent != NULL)
{
delete[] m_pParent;
m_pParent=NULL;
}
}
int CUnionFindSet::Find(int i) //查
{
if(i<0 || i>mn_N)
return -1;
int root=i;
if(root !=m_pParent[root]) //通过父结点-爷结点.....找到根结点,根结点记为root
{
root=m_pParent[i];
}
int t=i;
int p;
while(t !=root)
{
p=m_pParent[t];
m_pParent[t]=root; //直接写为根结点root
t=p; //父结点也写为根结点root
}
return root;
}
void CUnionFindSet::Union(int i, int j) //并, 采用Union处理以后,所有点只有一个父结点
{
if( (i<0 || i>mn_N) || (j<0 || j>mn_N))
return;
int ri = Find(i);
int rj = Find(j);
if(ri != rj)
m_pParent[i]=rj;
}
int CalcCompoment()
{
const int N=10;
CUnionFindSet ufs(N);
ufs.Union(2,6); //根据边初始化并查集
ufs.Union(5,6);
ufs.Union(1,8);
ufs.Union(2,9);
ufs.Union(5,3);
ufs.Union(4,8);
ufs.Union(4,0);
int * compoent =new int
;
memset(compoent,0, N*sizeof(int));
int i;
for(i=0; i<N; i++) // 计算每个岛的首府
compoent[ufs.Find(i)]++;
int nCompoent=0;
for(i=0; i<N; i++) // 计算每首府的数目
{
if(compoent[i]!=0)
nCompoent++;
}
delete [] compoent;
cout<<" "<<nCompoent<<endl;
return nCompoent;
}
int main()
{
CalcCompoment();
cout<<"执行完毕"<<endl;
return 0;
}
/*
#include<iostream>
using namespace std;
class CUnionFindSet
{
private:
int mn_N; //数目
public:
CunionFindSet(int n);
};
CUnionFindSet::CunionFindSet( int n) //构造函数
{
mn_N=n;
}
int main()
{
const int N=10;
CUnionFindSet ufs(N);
cout<<"执行完毕"<<endl;
return 0;
}*/
该问题可以并查集来解决
#include<iostream>
using namespace std;
class CUnionFindSet
{
private:
int mn_N; //数目
int *m_pParent; //只有一个父结点。
public:
CUnionFindSet(int n);
~CUnionFindSet();
void Union(int i, int j); //求并
int Find(int i); //查根
void Print() const;
};
CUnionFindSet::CUnionFindSet( int n) //构造函数
{
mn_N=n;
m_pParent=new int[mn_N];
for(int i=0; i<mn_N; i++)
m_pParent[i]=i;
}
CUnionFindSet::~CUnionFindSet()//析构函数
{
if(m_pParent != NULL)
{
delete[] m_pParent;
m_pParent=NULL;
}
}
int CUnionFindSet::Find(int i) //查
{
if(i<0 || i>mn_N)
return -1;
int root=i;
if(root !=m_pParent[root]) //通过父结点-爷结点.....找到根结点,根结点记为root
{
root=m_pParent[i];
}
int t=i;
int p;
while(t !=root)
{
p=m_pParent[t];
m_pParent[t]=root; //直接写为根结点root
t=p; //父结点也写为根结点root
}
return root;
}
void CUnionFindSet::Union(int i, int j) //并, 采用Union处理以后,所有点只有一个父结点
{
if( (i<0 || i>mn_N) || (j<0 || j>mn_N))
return;
int ri = Find(i);
int rj = Find(j);
if(ri != rj)
m_pParent[i]=rj;
}
int CalcCompoment()
{
const int N=10;
CUnionFindSet ufs(N);
ufs.Union(2,6); //根据边初始化并查集
ufs.Union(5,6);
ufs.Union(1,8);
ufs.Union(2,9);
ufs.Union(5,3);
ufs.Union(4,8);
ufs.Union(4,0);
int * compoent =new int
;
memset(compoent,0, N*sizeof(int));
int i;
for(i=0; i<N; i++) // 计算每个岛的首府
compoent[ufs.Find(i)]++;
int nCompoent=0;
for(i=0; i<N; i++) // 计算每首府的数目
{
if(compoent[i]!=0)
nCompoent++;
}
delete [] compoent;
cout<<" "<<nCompoent<<endl;
return nCompoent;
}
int main()
{
CalcCompoment();
cout<<"执行完毕"<<endl;
return 0;
}
/*
#include<iostream>
using namespace std;
class CUnionFindSet
{
private:
int mn_N; //数目
public:
CunionFindSet(int n);
};
CUnionFindSet::CunionFindSet( int n) //构造函数
{
mn_N=n;
}
int main()
{
const int N=10;
CUnionFindSet ufs(N);
cout<<"执行完毕"<<endl;
return 0;
}*/
相关文章推荐
- android 拨打电话与发送短信
- 什么是大数据概念
- robotframework笔记23
- Python format格式化输出
- 用RAII技术管理资源及其泛型实现
- websocket上传参数中文乱码问题解决
- Hbase 安装配置实验
- 强大的Core Image框架,各种滤镜处理图像
- 从MySQL官方Yum仓库安装MySQL5.6
- 企业集群平台LVS负载均衡算法分析与实现
- 企业集群平台LVS负载均衡算法分析与实现
- iOS巅峰之label描边
- 剑指offer(13):打印1到最大的n位数
- php 如何使用LigerUI grid插件
- Spark Streaming和Kafka整合开发指南(二)
- UIBezierPath画圆弧的记录
- Hadoop点滴
- Java设计模式——享元模式
- Meta标签大集合
- 【并发编程】CPU流水线的探秘之旅