SCOI2012 滑雪與時間膠囊 (最小生成樹)

2021-10-08 10:19:20 字數 1771 閱讀 6867

題目描述:

輸入的第一行是兩個整數n,m。

接下來1行有n個整數hi,分別表示每個景點的高度。

接下來m行,表示各個景點之間軌道分布的情況。每行3個整數,ui,vi,ki。表示編號為ui的景點和編號為vi的景點之間有一條長度為ki的軌道。

輸出描述:

輸出一行,表示a180285最多能到達多少個景點,以及此時最短的滑行距離總和。

資料範圍:

對於30%的資料,保證1<=n<=2000

對於100%的資料,保證1<=n<=100000

對於所有的資料,保證1<=m<=1000000, 1<-hi

<=100000000, 1<=ki

<= 100000000。

思路:首先根據題意,我們要根據每個點的高度 h 建乙個有向圖(並且用結構體儲存這些邊),那麼從點 1 開始bfs / dfs 就可以得到從點1 能到達的所有點的個數。那麼一定存在乙個樹形圖連線起這些點,但是如何使這個樹形圖為最小樹形圖(據說有個"朱-劉edmonds「演算法,但好像是o(nv)的複雜度,而且我不會),其實就是在有向圖裡求最小生成樹。

回到問題上,普通的 kru

skal

kruskal

kruska

l 會把所有的邊都當為無向邊來求解,但對於此問題只需要一些變形就可以達到有向邊的效果。首先我們結構體儲存的邊都是滿足條件的邊,即 h[a

]>=h

[b

]h[a]>=h[b]

h[a]

>=h

[b] ,所以我們可以以h[b

]h[b]

h[b]

為第一關鍵字從大到小排序,以邊權k

kk為 第二關鍵字從小到大排序,這樣當我們跑kru

skal

kruskal

kruska

l時,先拓展的都是第一層最高的點,那麼到拓展第二層的點時,第一層的都已經加入到了圖中,而與第二層相連的點都是在二層或一層的,所以這樣就能滿足拓展時點的高度非遞減;

#include

using

namespace std;

typedef

long

long ll;

const

int n =

1e6+7;

int h[n]

,p[n]

;bool vis[n]

;int n,m;

ll ans1,ans2;

struct nodee[n*2]

;int h[n]

,e[n*2]

,ne[n*2]

,idx;

void

add(

int a,

int b)

intfind

(int x)

bool

cmp(node a,node b)

void

dfs(

int x)

}void

kruskal()

}}intmain()

;if(h[b]

>=h[a]

)add

(b,a)

,e[i]=;

}dfs(1

);kruskal()

; cout<" "<"\n"

;return0;

}

SCOI2012 滑雪與時間膠囊

time limit 50 sec memory limit 128 mb submit 2362 solved 821 submit status discuss 膠囊消耗的情況下,以最短滑行距離滑到盡量多的景點的方案 即滿足經過景點數最大的前提下使得滑行總距離最小 你能幫他求出最短距離和景點數嗎...

生成樹 SCOI 2012 滑雪與時間膠囊

題意 乙個圖,每個點有乙個高度hi h i,邊有邊權。從 1 1 號點開始,每次從 i role presentation style position relative ii走到 j j 當且僅當存在一條 i role presentation style position relative ii...

2753 SCOI2012 滑雪與時間膠囊

time limit 50 sec memory limit 128 mb submit 2274 solved 793 submit status discuss a180285非常喜歡滑雪。他來到一座雪山,這裡分布著m條供滑行的軌道和n個軌道 之間的交點 同時也是景點 而且每個景點都有一編號i ...