hdu 3586 Information Disturbing 二分+树状DP

来源:互联网 发布:windows 10原版 下载 编辑:程序博客网 时间:2024/05/22 00:15

这种题目很容易看出二分,接着就是O(N)的验证了


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 1000 + 12;const int inf = 1000001;//别赋予太大值,会超出int n, m;struct EDGE{    int next, v, val;}edge[N * 2];int head[N];int cnt;void addedge(int u, int v, int val){    edge[cnt].v = v;    edge[cnt].val = val;    edge[cnt].next = head[u];    head[u] = cnt++;}int mid;int dp(int u, int fa){    bool flag = false;    int sum = 0;    for(int p = head[u]; p != -1; p = edge[p].next)    {        int v = edge[p].v;        if(v == fa)  continue;        int t = dp(v, u);        if(t > edge[p].val && edge[p].val <= mid)        {            t = edge[p].val;        }        flag = true;        sum += t;    }    if(!flag)  return inf;    return sum;}int main(){   while(scanf("%d%d", &n, &m) != EOF)   {       if(n == 0 && m == 0)  break;       cnt = 0;       memset(head, -1, sizeof(head));       int a, b, c;       int l = 1000;       int r = 1;       for(int i = 1; i <= n - 1; i++)       {           scanf("%d%d%d", &a, &b, &c);           l = min(l, c);           r = max(r, c);           addedge(a, b, c);           addedge(b, a, c);       }       int ans = inf;       while(l <= r)       {           mid = (l + r) >> 1;           //printf("mid =%d l =%d r=%d\n", mid, l, r);           if(dp(1, 0) <= m)           {               if(mid < ans) ans = mid;               r = mid - 1;           }           else           l = mid + 1;       }       if(ans != inf)       printf("%d\n", ans);       else       printf("-1\n");   }   return 0;}