原题链接:蓝桥杯历届试题-城市建设
解题思路:
本题的思路就是处理好了码头,就是求最小生成树:
1.处理码头:虚拟一个城市0,0与i城市建立码头的价值就等于w[i]
2.建立最小生成树MST
注意事项:
1.处理码头的时候,如果w[i]=-1,则不要加入这条边,或者设置w[i]=inf
2.建立最小生成树的时候,如果a,b两条边的价值w[a][b]的小于0,则不管是否连通,都要将这条边加入MST(题中求最小价值)
3.如果与城市0连接只有一条边,则不需要城市0,答案需要减去这条边的价值
参考代码:
#include <vector> #include <iostream> #include <cstdio> #include <algorithm> #define _for(i,a,b) for(int i=a;i<b;i++) #define inf (1<<28) using namespace std; typedef long long LL; struct edge{ int a,b,w=inf; bool operator < (const edge& o) const{ return w<o.w; } }; edge es[150005]; int w[10005],h[10005],vis[10005]; int _find(int x){ return x==h[x]?x:(h[x]=_find(h[x])); } int main() { int n,m,ans=0; scanf("%d%d",&n,&m); _for(i,1,m+1){ int a,b,c; scanf("%d%d%d",&a,&b,&c); if(c<es[i].w){ es[i].a=a; es[i].b=b; es[i].w=c; } } //1..将码头添加进边集 _for(i,1,n+1){ scanf("%d",&w[i]); if(w[i]!=-1){ es[++m].a=0; es[m].b=i; es[m].w=w[i]; } } //2..建立MST vector<int> G; _for(i,0,n+1)h[i]=i; sort(es+1,es+m+1); _for(i,1,m+1){ int a=es[i].a,b=es[i].b,c=es[i].w; int x=_find(a),y=_find(b); if(x!=y||c<=0){ if(a==0)G.push_back(i); h[x]=y; ans+=c; } } if(G.size()==1)ans-=es[G[0]].w; cout<<ans<<endl; }
0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复