51nod 1307繩子和重物

題目來源:  Codility
基準時間限制:1 秒 空間限制:131072 KB 分值: 40  難度:4級算法題
 收藏
 關注
有N條繩子編號 0 至 N - 1,每條繩子後面栓了一個重物重量爲Wi,繩子的最大負重爲Ci。每條繩子或掛在別的繩子下或直接掛在鉤子上(編號-1)。若是繩子下全部重物的重量大於繩子的最大負重就會斷掉(等於不會斷)。依次給出每條繩子的負重Ci、重物的重量Wi以及繩子會掛在以前的哪條繩子的下面,問最多掛多少個繩子而不會出現繩子斷掉的狀況。
 
例以下圖:
 
5, 2, -1
3, 3, 0
6, 1, -1
3, 1, 0
3, 2, 3
 
 
 
掛到第4個時會有繩子斷掉,因此輸出3。
 
 
Input
第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)。
Output
輸出1個數,最多掛到第幾個繩子,不會出現繩子斷掉的狀況。
Input示例
5
5 2 -1
3 3 0
6 1 -1
3 1 0
3 2 3
Output示例
3

思路:1.二分,二分枚舉最多能掛到第k個繩子,從第k個往第一個推,若發現當前能夠繩子能夠承載下全部重物則將k增大,不然將k減少。
   2.並查集,並查集自底向上維護每個繩子,若當前繩子掛的負重大於承重則從最後一個重物開始往前刪,直到負重小於承重,這樣下去等掛到根節點的時候全部的重物都已經掛完了,剩下沒有刪掉的個數即爲最多的個數

二分:
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 typedef long long LL;
 7 const int maxn = 50005;
 8 struct node {
 9     LL w, c, pre, cost;
10 }e[maxn];
11 LL n;
12 void reset()
13 {
14     for (int i = 0; i <= n; i++)
15         e[i].cost = 0;
16 }
17 int main()
18 {
19     ios::sync_with_stdio(false);
20     while (cin >> n) {
21         for (int i = 1; i <= n; i++) {
22             cin >> e[i].c >> e[i].w >> e[i].pre;
23             e[i].pre++;
24         }
25         int l = 1, r = n; bool flag;
26         while (l <= r) {
27             int mid = (l + r) >> 1;
28             flag = true;
29             reset();
30             for (int i = mid; i >= 1; i--) {
31                 e[i].cost += e[i].w;
32                 if (e[i].cost > e[i].c) {
33                     flag = false; break;
34                 }
35                 e[e[i].pre].cost += e[i].cost;
36             }
37             if (flag) l = mid + 1;
38             else r = mid - 1;
39         }
40         cout << r << endl;
41     }
42     return 0;
43 }

並查集:html

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 const int maxn = 50005;
 7 typedef long long LL;
 8 struct Task {
 9     int w, c, pre, cost;
10 }e[maxn];
11 int n, f[maxn];
12 int Find(int x)
13 {
14     if (f[x] != x)
15         f[x] = Find(f[x]);
16     return f[x];
17 }
18 int main()
19 {
20     ios::sync_with_stdio(false);
21     while (cin >> n) {
22         for (int i = 1; i <= n; i++) {
23             cin >> e[i].c >> e[i].w >> e[i].pre;
24             e[i].cost += e[i].w; e[i].pre++;
25             f[i] = i;
26         }
27         int ans = n;
28         for (int i = n; i >= 1; i--) {
29             while (e[i].cost > e[i].c) {
30                 int tmp = Find(ans);
31                 e[tmp].cost -= e[ans].w;
32                 ans--;
33             }
34             e[e[i].pre].cost += e[i].cost;
35             f[i] = e[i].pre;
36         } 
37         cout << ans << endl;
38     }
39     return 0;
40 }
相關文章
相關標籤/搜索