补题系列 1 最小布线

来源:互联网 发布:淘宝店铺宝贝卖点怎么写 编辑:程序博客网 时间:2024/06/05 15:19
北航数据结构Judge网站原题,抄袭被查重后果自负!5个月之前,由于数据结构期末考试不考图的大题,所以图学得不扎实,这里特地补上!【问题描述】北航主要办公科研楼有新主楼、逸夫楼、如心楼、办公楼、图书馆、主楼、一号楼&hellip;。北航网络中心计划要给相关建筑物间铺设光缆进行网络连通,请给出用料最少的铺设方案。编写程序输入一个办公区域分布图及建筑物之间的距离,计算出用料最少的铺设方案(只有一组最优解,不用考虑多组解)。要求采用Prim或Kruskal算法实现。【输入形式】办公区域分布图的顶点(即建筑物)按照自然数(0,1,2,n-1)进行编号,从标准输入中首先输入两个正整数,分别表示线路图的顶点的数目和边的数目,然后在接下的行中输入每条边的信息,每条边占一行,具体形式如下:<n> <e><id> <vi> <vj> <weight>...即顶点vi和vj之间边的权重是weight,边的编号是id。【输出形式】输出铺设光缆的最小用料数,然后另起一行输出需要铺设的边的id,并且输出的id值按照升序输出。【样例输入】 6 101 0 1 6002 0 2 1003 0 3 5004 1 2 5005 2 3 5006 1 4 3007 2 4 6008 2 5 4009 3 5 20010 4 5 600【样例输出】15002 4 6 8 9#include<iostream>#include<algorithm>#define MAX 300using namespace std;struct routes{    int num;    int a,b;    int len;};routes road[MAX];int pre[MAX];int ans[MAX];int allusenum=0;int find(int root){    int son=root;    int temp;    while(root!=pre[root])        root=pre[root];    while(son!=root)    {        temp=pre[son];        pre[son]=root;        son=temp;    }    return root;}bool cmp(const routes a,const routes b){    return a.len <b.len ;}int kruskal(int routenum){    int i,j=0;    sort(road,road+routenum,cmp);    int sum=0;    for(i=0;i<routenum;i++)    {        int roota=find(road[i].a );        int rootb=find(road[i].b );        if(roota!=rootb)        {            sum+=road[i].len ;            ans[j++]=road[i].num ;            allusenum++;            pre[roota]=rootb;        }    }    return sum;}int main(){    int n,routenum;    cin>>n>>routenum;    for(int i=0;i<MAX;i++)        pre[i]=i;    for(int i=0;i<routenum;i++)        cin>>road[i].num >>road[i].a >>road[i].b >>road[i].len ;    int answer=kruskal(routenum);        cout<<answer<<endl;    sort(ans,ans+allusenum);    for(int i=0;i<allusenum;i++)        cout<<ans[i]<<" ";    cout<<endl;}