1. 程式人生 > >[HDU3586]Information Disturbing(DP + 二分)

[HDU3586]Information Disturbing(DP + 二分)

cli 分答 mda php val har sizeof info bin

傳送門

二分答案,再 DP,看看最終結果是否小於 m

——代碼

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #define N 1001
 5 #define max(x, y) ((x) > (y) ? (x) : (y))
 6 
 7 int n, m, cnt, ans;
 8 int a[N], sum[N], head[N], to[N << 1], val[N << 1
], next[N << 1]; 9 bool vis[N]; 10 11 inline int read() 12 { 13 int x = 0, f = 1; 14 char ch = getchar(); 15 for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1; 16 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0; 17 return x * f;
18 } 19 20 inline void add(int x, int y, int z) 21 { 22 to[cnt] = y; 23 val[cnt] = z; 24 next[cnt] = head[x]; 25 head[x] = cnt++; 26 } 27 28 inline void dfs(int u, int x) 29 { 30 int i, v; 31 vis[u] = 1; 32 for(i = head[u]; i ^ -1; i = next[i]) 33 { 34
v = to[i]; 35 if(!vis[v]) 36 { 37 dfs(v, x); 38 if(val[i] <= x) 39 { 40 if(val[i] < sum[v]) sum[u] += val[i]; 41 else sum[u] += sum[v]; 42 } 43 else sum[u] += sum[v]; 44 } 45 } 46 } 47 48 inline bool check(int x) 49 { 50 memset(vis, 0, sizeof(vis)); 51 memset(sum, 0, sizeof(sum)); 52 for(int i = 2; i <= n; i++) 53 if(a[i] == 1) 54 sum[i] = m + 1; 55 dfs(1, x); 56 return sum[1] <= m; 57 } 58 59 int main() 60 { 61 int i, x, y, z, mid; 62 while(1) 63 { 64 cnt = 0; 65 n = read(); 66 m = read(); 67 if(!n && !m) break; 68 memset(a, 0, sizeof(a)); 69 memset(head, -1, sizeof(head)); 70 for(i = 1; i < n; i++) 71 { 72 a[x = read()]++; 73 a[y = read()]++; 74 z = read(); 75 add(x, y, z); 76 add(y, x, z); 77 } 78 x = 1, y = m, ans = -1; 79 while(x <= y) 80 { 81 mid = (x + y) >> 1; 82 if(check(mid)) ans = mid, y = mid - 1; 83 else x = mid + 1; 84 } 85 printf("%d\n", ans); 86 } 87 return 0; 88 }
View Code

[HDU3586]Information Disturbing(DP + 二分)