1307 繩子與重物
1.0 秒 131,072.0 kb 40 分 4級題
有n條繩子編號 0 至 n - 1,每條繩子後面栓了乙個重物重量為wi,繩子的最大負重為ci。每條繩子或掛在別的繩子下或直接掛在鉤子上(編號-1)。如果繩子下所有重物的重量大於繩子的最大負重就會斷掉(等於不會斷)。依次給出每條繩子的負重ci、重物的重量wi以及繩子會掛在之前的哪條繩子的下面,問最多掛多少個繩子而不會出現繩子斷掉的情況。
例如下圖:
掛到第4個時會有繩子斷掉,所以輸出3。
輸入第1行:1個數n,表示繩子的數量(1 <= n <= 50000)。
第2 - n + 1行:每行3個數,ci, wi, pi,ci表示最大負重,wi表示重物的重量,pi表示掛在哪個繩子上,如果直接掛在鉤子上則pi = -1(1 <= ci <= 10^9,1 <= wi <= 10^9,-1 <= pi <= n - 2)。
輸出輸出1個數,最多掛到第幾個繩子,不會出現繩子斷掉的情況。
輸入樣例
55 2 -1
3 3 0
6 1 -1
3 1 0
3 2 3
輸出樣例
3認真讀題啊!!!
「給出每條繩子的負重ci、重物的重量wi以及繩子會掛在之前的哪條繩子的下面,問最多掛多少個繩子而不會出現繩子斷掉的情況。」
第i條繩子都是掛在之前的繩子的下面的
所以可以並查集寫。。。可以從前往後掛,也就是依次**把兒子掛到父節點(把第i條繩子掛在1 ~ i - 1的某一條繩子)上,然後返回到父節點,以及父節點的父節點。。是個回溯(最後回到-1,肯定都是要掛在鉤子上的嘛)**的過程。。。判斷掛這條繩子會不會使某條繩子斷掉,斷掉就輸出當前繩子的編號,然後return 0(感覺時間複雜度會高)
也可以從後往前掛,如果繩子要斷掉了。。就從最後開始刪除兒子節點()。。看看最後有多少條繩子是掛上去的(return res),就是答案了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int maxn =
2e5+5;
int pre[maxn]
;int sum[maxn]
;int c[maxn]
,w[maxn]
,p[maxn]
;int n;
intfind
(int x)
intsolve()
sum[p[i]]+
= sum[i]
; pre[i]
= p[i];}
return res;
}int
main()
int ans =
solve()
;printf
("%d\n"
,ans)
;return0;
}
資料結構 帶權並查集
顧名思義,就是在維護集合關係的樹中新增邊權的並查集,這樣做可以維護更多的資訊。引入題目 比如這道題,如果使用普通的並查集則無法處理,因為普通的並查集只能夠刻畫兩個物品是否屬於同乙個集合。因此這時候就要使用能夠記錄更多資訊的帶權並查集。在閱讀前,需要先掌握並查集的知識。結合題目講解 對於乙個物種 一類...
資料結構 帶權 種類並查集
給出乙個區間的長度 n,及 m 個子區間和,形如 x y z,表示 子區間 x,y 的和為 z 如果乙個 子區間和 與前面的 子區間和 衝突,即為錯誤 而且這個 子區間和 將在接下來的判斷中被忽略 求總錯誤個數。帶權並查集 include include include using namespac...
樹形結構 並查集 帶權並查集
定義 帶權並查集即是結點存有權值資訊的並查集。適用 當兩個元素之間的關係可以量化,並且關係可以合併時,可以使用帶權並查集來維護元素之間的關係。權值 帶權並查集每個元素的權通常描述其與並查集中祖先的關係,這種關係如何合併,路徑壓縮時就如何壓縮。與並查集的區別 帶權並查集可以推算集合內點的關係,而一般並...