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