poj2421 Constructing Roads

描述:

有n个村庄,编号为1 ,2 ,3 ,,,n  应该建造道路使他们互相可达

对输入数据

3
0 990 692
990 0 179
692 179 0
1
1 2
意思有3个村庄,

0 990 692
990 0 179
692 179 0
意思是1号到1,2,3的距离分别为0 990 692

1
1 2
意思是有一条道路已经接通,就是1号与2号间的道路

解法:

kruskal算法,建造最小生成树即可

#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
class road//定义道路的数据类型
{
public:
	int l,r;
	int dis;
};
vector<road>a;//存储输入的道路
int parent[200];//并查集的结构,parent[i]表示i的父节点
int Root(int a)//查询a的根节点
{
	if(parent[a]==a)
	{
		return a;
	}
	return parent[a]=Root(parent[a]);
}
void Merge(int a,int b)//将a和b所在的集合并起来
{
	int ra=Root(a);
	int rb=Root(b);
	parent[ra]=rb;
}
bool cmp(road a,road b)//排序函数
{
	return a.dis<b.dis;
}
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		parent[i]=i;//并查集的初始化
	}
	for(int i=0;i<n;i++)
	{
		road tmp;
		tmp.l=i;
		for(int j=0;j<n;j++)
		{
			tmp.r=j;
			cin>>tmp.dis;
			a.push_back(tmp);
		}
	}
	int Q;
	cin>>Q;
	while(Q--)
	{
		int l,r;
		cin>>l>>r;
		Merge(l-1,r-1);
	}
	sort(a.begin(),a.end(),cmp);//排序
	int size=a.size();
	int ans=0;
	for(int i=0;i<size;i++)
	{
		if(Root(a[i].l)!=Root(a[i].r))//假如不在同一集合中
		{
			Merge(a[i].l,a[i].r);
			ans+=a[i].dis;
		}
	}
	cout<<ans<<endl;
	return 0;
}


你可能感兴趣的:(poj2421 Constructing Roads)