poj2421 Constructing Roads

来源:互联网 发布:希特勒恶魔的崛起知乎 编辑:程序博客网 时间:2024/05/29 16:20

描述:

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

对输入数据

30 990 692990 0 179692 179 011 2
意思有3个村庄,

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

11 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;}