(最小生成樹 思維)城市建設

2021-09-13 10:36:46 字數 3505 閱讀 9483

歷屆試題 城市建設  

時間限制:1.0s   記憶體限制:256.0mb

問題描述

棟棟居住在乙個繁華的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 4

1 3 -1

2 3 3

2 4 5

4 5 10

-1 10 10 1 1

樣例輸出

樣例說明

建設第2、3、4條道路,在地點4、5建設碼頭,總的花費為9。

資料規模和約定

對於20%的資料,1<=n<=10,1<=m<=20,0<=c<=20,w_i<=20;

對於50%的資料,1<=n<=100,1<=m<=1000,-50<=c<=50,w_i<=50;

對於70%的資料,1<=n<=1000;

對於100%的資料,1 <= n <= 10000,1 <= m <= 100000,-1000<=c<=1000,-1<=w_i<=1000,w_i≠0。

首先是對題目的理解:如果有某倆個結點不通,我們可以通過在這倆個地方架設碼頭,只要有碼頭的地方都是相通的;

1:我們可以通過kruskal演算法求出花費最少的路徑

2:怎麼處理架設碼頭的點呢?我們可以另外架設乙個結點0,將所有假設碼頭的點和0結點相連然後在處理;

3:因為架設碼頭會多出乙個點,所以我們要分開判斷,以防止結點數的判斷上出問題

4:最坑的是有的路徑可以盈利,為了使花費最小,這些路徑不管怎麼樣都要加上,不能像正常的kruskal演算法因為已經有了更小的連線就不加了;

題解     原文:

在看題解前,一直是50分,看後恍然大悟!

(1) 50分

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define eps (1e-8)

#define max 0x3f3f3f3f

#define u_max 1844674407370955161

#define l_max 9223372036854775807

#define i_max 2147483647

#define re register

#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]

#define nth(k,n) nth_element(a,a+k,a+n); // 將 第k大的放在k位

#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 約瑟夫

#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,離散化

#define catalan c(2n,n)-c(2n,n-1) (1,2,5,14,42,132,429...) // 卡特蘭數

using namespace std;

inline int read()

while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}typedef long long ll;

const double pi = atan(1.)*4.;

const int inf = 0x3f3f3f3f;

const ll inf = 0x3f3f3f3f3f3f3f3fll;

const int m=63;

const int n=1e5+5;

int n,m;

struct funf[n];

int a[n],per[n];

int findd(int x)

bool u(int x,int y)

return false;

}bool cmp(fun a,fun b)

while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}typedef long long ll;

const double pi = atan(1.)*4.;

const int inf = 0x3f3f3f3f;

const ll inf = 0x3f3f3f3f3f3f3f3fll;

const int m=63;

const int n=1e5+5;

int n,m,p,num;

struct funf[n];

int a[n],per[n];

int findd(int x)

bool u(int x,int y)

return false;

}bool cmp(fun a,fun b)

int kcl(int nn,int len)

else

if(num==nn-1)

}for(int i=h;ireturn ans;

}int main()

int ans1=kcl(n,m);

if(numprintf("%d\n",kcl(n+1,p));

else

printf("%d\n",min(ans1,kcl(n+1,p)));

return 0;

}

藍橋杯歷屆試題 城市建設 (最小生成樹)

歷屆試題 城市建設 時間限制 1.0s 記憶體限制 256.0mb 問題描述 棟棟居住在乙個繁華的c市中,然而,這個城市的道路大都年久失修。市長準備重新修一些路以方便市民,於是找到了棟棟,希望棟棟能幫助他。c市中有n個比較重要的地點,市長希望這些地點重點被考慮。現在可以修一些道路來連線其中的一些地點...

HNOI2010 城市建設 動態最小生成樹

傳送門 大意 給你一棵樹,每次永久修改一條邊權,詢問當前最小生成樹 做法真的妙妙的 考慮到無論我們怎麼修改某條邊的邊權 都總有一些邊可以被選到 也總有一些邊不會被選到 因此就引入了兩個操作 c on trac tion contraction contra ctio n 我們將當前分治區間的所有要修...

最小生成樹 城市公交網建設問題

城市公交網建設問題 問題描述 有一張城市地圖,圖中的頂點為城市,無向邊代表兩個城市間的連通關係,邊上的權為在這兩個城市之間修建高速公路的造價,研究後發現,這個地圖有乙個特點,即任一對城市都是連通的。現在的問題是,要修建若干高速公路把所有城市聯絡起來,問如何設計可使得工程的總造價最少?輸入格式 n 城...