蓝桥杯 城市建设 (Kruskal)

网友投稿 619 2022-08-26

蓝桥杯 城市建设 (Kruskal)

蓝桥杯 城市建设 (Kruskal)

问题描述

栋栋居住在一个繁华的 C 市中,然而,这个城市的道路大都年久失修。市长准备重新修一些路以方便市民,于是找到了栋栋,希望栋栋能帮助他。C 市中有 n 个比较重要的地点,市长希望这些地点重点被考虑。现在可以修一些道路来连接其中的一些地点,每条道路可以连接其中的两个地点。另外由于 C 市有一条河从中穿过,也可以在其中的一些地点建设码头,所有建了码头的地点可以通过河道连接。栋栋拿到了允许建设的道路的信息,包括每条可以建设的道路的花费,以及哪些地点可以建设码头和建设码头的花费。市长希望栋栋给出一个方案,使得任意两个地点能只通过新修的路或者河道互达,同时花费尽量小。

输入格式

输入的第一行包含两个整数 n, m,分别表示 C 市中重要地点的个数和可以建设的道路条数。所有地点从 1 到 n 依次编号。接下来 m 行,每行三个整数 a, b, c,表示可以建设一条从地点 a 到地点 b 的道路,花费为 c 。若 c 为正,表示建设是花钱的,如果 c 为负,则表示建设了道路后还可以赚钱(比如建设收费道路)。接下来一行,包含 n 个整数 w_1, w_2, …, w_n 。如果 w_i 为正数,则表示在地点i建设码头的花费,如果 w_i 为 -1 ,则表示地点i无法建设码头。输入保证至少存在一个方法使得任意两个地点能只通过新修的路或者河道互达。

输出格式

输出一行,包含一个整数,表示使得所有地点通过新修道路或者码头连接的最小花费。如果满足条件的情况下还能赚钱,那么你应该输出一个负数。

样例输入

5 51 2 41 3 -12 3 32 4 54 5 10-1 10 10 1 1

样例输出

9

思路

先说一下这道题的坑点吧!

原题中 ​​市长希望栋栋给出一个方案,使得任意两个地点能只通过新修的路或者河道互达,同时花费尽量小。​​ 这句话很容易让人误解为图中两点之间只能有一条路径,于是我就神奇的 WA 了。(一定要加上所有的负权边)

对于有码头的城市,我们为其创建一条从 i i 到 00

结果只有陆路,不包含水路,即舍掉 0 0 号点,此时按照 Kruskal 算法的思想,贪心找出连通所有城市且总花费最低的方案,记为 ans1ans1结果包含水路,依然按照 Kruskal 算法的思想,找出连通所有城市以及 0 0 号点的最小花费方案,记为 ans2ans2

则最终的答案为: min(ans1,ans2) min ( a n s 1 , a n s 2 )

AC 代码

#include #include #include #include #include #include #include #define IO \ ios::sync_with_stdio(false); \ cin.tie(0); \ cout.tie(0);using namespace std;const int maxn = 1e6 + 10;typedef pair P;struct node{ int from; int to; int cost; int next; friend bool operator<(const node &x,const node &y){ return x.cost < y.cost; }}edge[maxn];int head[maxn],tot;int n,m;int fa[maxn],rk[maxn];void init(){ memset(head,-1,sizeof(head)); tot = 0;}void addedge(int u,int v,int cost){ edge[tot].from = u; edge[tot].to = v; edge[tot].cost = cost; edge[tot].next = head[u]; head[u] = tot++;}void init_set(){ memset(rk,0,sizeof(rk)); for(int i=0;irk[y]) fa[y] = x; else{ fa[x] = y; if(rk[x] == rk[y]) ++rk[y]; } return true;}int result1(){ // 包含 0 号点 init_set(); int sum = 0; for(int i=0;i>n>>m; for(int i=0;i>u>>v>>c; addedge(u,v,c); } for(int i=1;i<=n;i++){ int x; cin>>x; if(x!=-1){ addedge(i,0,x); } } sort(edge,edge+tot); cout<

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Codeforces 712 C. Memory and De-Evolution (思维)
下一篇:codevs 2498 IncDec Sequence (差分数组)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~