1. 程式人生 > >51nod 1307 繩子與重物 (標記父節點更新即可)

51nod 1307 繩子與重物 (標記父節點更新即可)

代碼 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 3
Output示例
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 繩子與重物 (標記父節點更新即可)