日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1732: 数花费(Kruscal)

發(fā)布時(shí)間:2024/9/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1732: 数花费(Kruscal) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1732: 數(shù)花費(fèi)
時(shí)間限制: 1 Sec 內(nèi)存限制: 128 MB

[提交][狀態(tài)][討論版]
題目描述
 棟棟居住在一個(gè)繁華的C市中,然而,這個(gè)城市的道路大都年久失修。市長準(zhǔn)備重新修一些路以方便市民,于是找到了棟棟,希望棟棟能幫助他。
C市中有n個(gè)比較重要的地點(diǎn),市長希望這些地點(diǎn)重點(diǎn)被考慮。現(xiàn)在可以修一些道路來連接其中的一些地點(diǎn),每條道路可以連接其中的兩個(gè)地點(diǎn)。另外由于C市有一條河從中穿過,也可以在其中的一些地點(diǎn)建設(shè)碼頭,所有建了碼頭的地點(diǎn)可以通過河道連接。
棟棟拿到了允許建設(shè)的道路的信息,包括每條可以建設(shè)的道路的花費(fèi),以及哪些地點(diǎn)可以建設(shè)碼頭和建設(shè)碼頭的花費(fèi)。
市長希望棟棟給出一個(gè)方案,使得任意兩個(gè)地點(diǎn)能只通過新修的路或者河道互達(dá),同時(shí)花費(fèi)盡量小。
輸入
輸入的第一行包含兩個(gè)整數(shù)n, m,分別表示C市中重要地點(diǎn)的個(gè)數(shù)和可以建設(shè)的道路條數(shù)。所有地點(diǎn)從1到n依次編號。
接下來m行,每行三個(gè)整數(shù)a, b, c,表示可以建設(shè)一條從地點(diǎn)a到地點(diǎn)b的道路,花費(fèi)為c。若c為正,表示建設(shè)是花錢的,如果c為負(fù),則表示建設(shè)了道路后還可以賺錢(比如建設(shè)收費(fèi)道路)。
接下來一行,包含n個(gè)整數(shù)w_1, w_2, …, w_n。如果w_i為正數(shù),則表示在地點(diǎn)i建設(shè)碼頭的花費(fèi),如果w_i為-1,則表示地點(diǎn)i無法建設(shè)碼頭。
輸入保證至少存在一個(gè)方法使得任意兩個(gè)地點(diǎn)能只通過新修的路或者河道互達(dá)。
輸出
輸出一行,包含一個(gè)整數(shù),表示使得所有地點(diǎn)通過新修道路或者碼頭連接的最小花費(fèi)。如果滿足條件的情況下還能賺錢,那么你應(yīng)該輸出一個(gè)負(fù)數(shù)。

樣例輸入

5 5 1 2 4 1 3 -1 2 3 3 2 4 5 4 5 10 -1 10 10 1 1

樣例輸出

9

提示

建設(shè)第2、3、4條道路,在地點(diǎn)4、5建設(shè)碼頭,總的花費(fèi)為9。

對于20%的數(shù)據(jù),1<=n<=10,1<=m<=20,0<=c<=20,w_i<=20;

對于50%的數(shù)據(jù),1<=n<=100,1<=m<=1000,-50<=c<=50,w_i<=50;

對于70%的數(shù)據(jù),1<=n<=1000;

對于100%的數(shù)據(jù),1 <= n <= 10000,1 <= m <= 100000,-1000<=c<=1000,-1<=w_i<=1000,w_i≠0。

來源
/*
跑兩遍kruscal。
第一遍跑沒有碼頭的。
第二遍跑加上碼頭的。
對于第一遍沒有碼頭的而言,可能無法生成最小生成樹。
判斷條件就是: 根節(jié)點(diǎn)(pre[i] == i)個(gè)數(shù)是否等于1
不管帶不帶碼頭跑生成樹,有錢賺的肯定建它啊!!
對于第二遍,由于城市數(shù)量最大達(dá)10000,碼頭之間的邊無法暴力處理。
此時(shí)可以引入一個(gè)虛擬節(jié)點(diǎn)0,讓所有可以建碼頭的城市通過節(jié)點(diǎn)0連接起來。
最后算答案的時(shí)候,如果沒有碼頭無法連通,那么就直接取有碼頭的那個(gè)答案,
否則取兩者之間較小值。
*/
Ac_code:

#include <bits/stdc++.h>using namespace std; const int maxn= 1e5+5; #define INF 0x3f3f3f3f struct Edge {int s,e;int val;bool operator<(const Edge a)const{return val < a.val;} } data[maxn<<1]; int pre[maxn]; int myFind(int x) {int r = x;while(pre[r]!= r){r = pre[r];}int i = x,j;while(pre[i]!= r){j = pre[i];pre[i] = r;i = j;}return r;//return pre[x]==x?x:pre[x]=myFind(pre[x]); } int kruscal(int n,int m) {for(int i = 1; i <= n; i++){pre[i] = i;}sort(data,data+m);int ans = 0;for(int i = 0; i < m; i++){if(data[i].val == INF) continue; //不能建碼頭int fx = myFind(data[i].s);int fy = myFind(data[i].e);if(fx != fy || data[i].val < 0)//賺錢的路一定建{ans += data[i].val;pre[fx] = fy;}}return ans; } int main() {int n,m;scanf("%d%d",&n,&m);for(int i = 0; i < m; i++){scanf("%d%d%d",&data[i].s,&data[i].e,&data[i].val);}int t;for(int i = m; i < n+m; i++){scanf("%d",&t);data[i].s = 0; //通過虛擬一個(gè)0點(diǎn)連接碼頭之間構(gòu)成的邊data[i].e = i-m+1;if(t == -1)data[i].val = INF;elsedata[i].val = t;}int ans1 = kruscal(n,m); //無碼頭int cnt = 0;for(int i = 1; i <= n; i++)//判斷無碼頭能否連通{if(pre[i]==i) cnt++;}int ans2 = kruscal(n,m+n);//有碼頭printf("%d\n",(cnt==1?min(ans1,ans2):ans2));return 0; }

總結(jié)

以上是生活随笔為你收集整理的1732: 数花费(Kruscal)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。