51nod 1307 繩子與重物 (標記父節點更新即可)
阿新 • • 發佈:2017-10-25
代碼 col problem 標記 src space ima 大於 output
1307 繩子與重物
基準時間限制: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 3Output示例
3
題目意思很明確了,就是繩子有最大載重,下面掛東西,問最多掛多少個不掉下來。
實際上是求掉下來的那一個-1即可。
我的想法是用一個parent[i]表示第i個節點的父節點,即掛在哪個節點上。
每次多掛一個就把它的所有祖先節點的載重增加,同時與最大載重量比較。
代碼:
#include <iostream> #include <algorithm> #include <map> #include <vector> using namespace std; typedef long long ll; #define INF 2147483647 int parent[50010]; struct node{ int c,w,p; }a[50010]; int main(){ int n; cin >> n; fill(parent,parent + n, -2); //父節點的索引號 for(int i = 0;i < n; i++) cin >> a[i].c >> a[i].w >> a[i].p,parent[i] = a[i].p; for(int i = 0;i < n; i++){ parent[i] = a[i].p; //從i一直往上找,順便比較 ,如果超重直接輸出並return 0; int t = i; while(parent[t] != -1){ a[parent[t]].w += a[i].w; if(a[parent[t]].c < a[parent[t]].w){ cout << i << endl; return 0; } t = parent[t]; } } //所有的都能掛上,輸出n。 cout << n <<endl; return 0; }
51nod 1307 繩子與重物 (標記父節點更新即可)