描述:
有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;
}