NYOJ - 38:布线问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wingrez/article/details/89632273

布线问题

来源:NYOJ

标签:最小生成树

参考资料:

相似题目:

题目

南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
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开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。

输出

每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。

输入样例

输出样例

1
4 6
1 2 10
2 3 10
3 1 10
1 4 1
2 4 1
3 4 1
1 3 5 6

样例解释

4

解题思路

学校里楼之间使用Prim算法求最小生成树。

参考代码

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define MAXN 505 //顶点的最大个数 
using namespace std;

struct Edge{
    int v; //顶点 
	int u; //下一个顶点 
    int w; //权值 
    Edge(int v,int u,int w):v(v),u(u),w(w){}
    bool operator < (const Edge &e) const {
        return w>e.w;
    }
};

vector<Edge> adj[MAXN]; //agj[v]:与v相连的边 
vector<Edge> mst; //最小生成树 
priority_queue<Edge> pq; //优先队列,存放横切边 
int vis[MAXN]; //访问标志 

void Prim(); //Prim算法,计算最小生成树 
void visit(int v); //设置访问标志,并将与v相邻结点(未被访问)的边加入优先队列中 

void Prim(){ 
    visit(1);
    while(!pq.empty()){
        Edge e=pq.top();
        pq.pop();
        if(vis[e.v] && vis[e.u]) continue;
        mst.push_back(e);
        if(!vis[e.v]) visit(e.v);
        if(!vis[e.u]) visit(e.u);
    }
}

void visit(int v){ 
    vis[v]=1;
    for(vector<Edge>::iterator i=adj[v].begin(); i!=adj[v].end();i++){
        if(!vis[(*i).u]){
            pq.push(*i);
        }
    }
}

int N;
int n,m;
int v,u,w;

int main(){
	scanf("%d",&N);
	while(N--){
		memset(vis,0,sizeof(vis));
		mst.clear();
		for(int i=0;i<MAXN;i++) adj[i].clear();
		while(!pq.empty()) pq.pop();

		scanf("%d%d",&n,&m);
		while(m--){
			scanf("%d%d%d",&v,&u,&w);
			adj[v].push_back(Edge(v,u,w));
			adj[u].push_back(Edge(u,v,w)); 
		}
		
		int mn=100; //外界供电设备到学校的最短距离 
		for(int i=1;i<=n;i++){
			scanf("%d",&w); 
			if(mn>w) mn=w;
		}
		
		Prim();
	    int ans=0;
	    for(vector<Edge>::iterator i=mst.begin();i!=mst.end();i++){
	    	ans+=(*i).w;
		}
	    printf("%d\n",ans+mn);
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wingrez/article/details/89632273