nyoj 38 布线问题(prim)

来源:互联网 发布:三菱网络模块 编辑:程序博客网 时间:2024/05/16 15:33
描述
南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少
输入
第一行是一个整数n表示有n组测试数据。(n<5)
每组测试数据的第一行是两个整数v,e.
v表示学校里楼的总个数(v<=500)
随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
(楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。
输出
每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。
样例输入
14 61 2 102 3 103 1 101 4 12 4 13 4 11 3 5 6
样例输出

4

思路:用最小生成树prim算法,需要注意的是,因为要有一个接外电源,花费最小的话,要找一个接外电源花费最小的点开始prim

#include<iostream>#include<functional>#include<cstdio>#include<queue>#include<cstring>using namespace std;#define INF 999999999int n,m;int Map[505][505],book[505];int v[505],cas;struct node{    int place;    int value;    friend bool operator < (node n1,node n2){        if(n1.value!=n2.value)            return n1.value>n2.value;//优先队列,按照花费从小到大排        else            return n1.place>n2.place;    }}u,e;int init(){    int i,j;    for(i=1;i<=n;i++){        for(j=1;j<=n;j++){            Map[i][j]=INF;        }    }}void Prim(int st){    memset(book,0,sizeof(book));    priority_queue<node>q;    while(!q.empty()) q.pop();    int i,j,sum;    i=st;    //printf("i=%d\n",i);    for(j=1;j<=n;j++){        if(Map[i][j]!=INF){            u.place=j;            u.value=Map[i][j];            q.push(u);           // printf("R u.p=%d u.v=%d\n",u.place,u.value);        }    }    book[i]=1;    cas=1;    sum=v[i];    while(!q.empty()){        u=q.top();        q.pop();        if(book[u.place]==1)//已经走过的点不算        continue;           cas++;//记录走过点的个数           sum+=u.value;//走过点的花费           if(cas==n){            printf("%d\n",sum);            break;           }        book[u.place]=1;      //  printf("C u.p=%d u.v=%d\n",u.place,u.value);        i=u.place;        for(j=1;j<=n;j++){            if(Map[i][j]!=INF &&book[j]==0){                e.place=j;                e.value=Map[i][j];                q.push(e);              //  printf("R e.p=%d e.v=%d\n",e.place,e.value);            }        }    }}int main(){    int t,a,b,c;    int i,j,mm;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        init();//先把地图初始化        while(m--){            scanf("%d%d%d",&a,&b,&c);            if(Map[a][b]>c){                 Map[a][b]=c;                 Map[b][a]=c;            }        }            mm=INF;            for(i=1;i<=n;i++){                scanf("%d",&v[i]);                if(v[i]<mm){                    mm=v[i];                    j=i;                }            }            Prim(j);//从接外电源花费最小的点    }    return 0;}


0 0
原创粉丝点击