zoukankan      html  css  js  c++  java
  • UVALive 4015 树形dp

     题目大意:

    从一个根节点出发,走最多 x 的长度,问最多能走过多少个节点,图保证是一棵树

    dp[0][i][j] , 表示走从i点为根的子树走过了j个点最后回到 i 最少需要多少时间
    dp[1][i][j] , 同理,但表示不需要回到 i
    那么由儿子不断向父亲更新,有4种情况

    1.if(dp[0][u][k+j]<0 || dp[0][u][k+j]>dp[0][v][j]+dp[0][u][k]+2*e[i].d)
                        dp[0][u][k+j]=dp[0][v][j]+dp[0][u][k]+2*e[i].d;

    2.if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[0][v][j]+dp[0][u][k]+e[i].d)
                        dp[1][u][k+j]=dp[0][v][j]+dp[0][u][k]+e[i].d;

    3.if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[1][v][j]+dp[0][u][k]+e[i].d)
                        dp[1][u][k+j]=dp[1][v][j]+dp[0][u][k]+e[i].d;

    4.if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[0][v][j]+dp[1][u][k]+2*e[i].d)
                        dp[1][u][k+j]=dp[0][v][j]+dp[1][u][k]+2*e[i].d;

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 #define N 505
      9 #define ll long long
     10 ll dp[2][N][N];
     11 int fa[N] , n , m;
     12 int first[N],k;
     13 
     14 struct Edge{
     15     int y , next , d;
     16     Edge(int y=0 , int next=0 , int d=0):y(y),next(next),d(d){}
     17 }e[N<<1];
     18 
     19 void add_edge(int x , int y , int d)
     20 {
     21     e[k] = Edge(y , first[x] , d);
     22     first[x] = k++;
     23 }
     24 
     25 void dfs(int u)
     26 {
     27     dp[0][u][1] = 0;
     28     for(int i=first[u] ; ~i ; i=e[i].next){
     29         int v = e[i].y;
     30         dfs(v);
     31         for(int k=n ; k>=1 ; k--)
     32         {
     33             if(dp[0][u][k]<0) continue;
     34             for(int j=1 ; j<n ; j++){
     35                 if(dp[0][v][j]<0) continue;
     36                 if(dp[0][u][k+j]<0 || dp[0][u][k+j]>dp[0][v][j]+dp[0][u][k]+2*e[i].d)
     37                     dp[0][u][k+j]=dp[0][v][j]+dp[0][u][k]+2*e[i].d;
     38                 if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[0][v][j]+dp[0][u][k]+e[i].d)
     39                     dp[1][u][k+j]=dp[0][v][j]+dp[0][u][k]+e[i].d;
     40 
     41                 if(dp[1][v][j]<0) continue;
     42                 if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[1][v][j]+dp[0][u][k]+e[i].d)
     43                     dp[1][u][k+j]=dp[1][v][j]+dp[0][u][k]+e[i].d;
     44             }
     45             if(dp[1][u][k]<0) continue;
     46             for(int j=1 ; j<=n ; j++){
     47                 if(dp[0][v][j]<0) continue;
     48                 if(dp[1][u][k+j]<0 || dp[1][u][k+j]>dp[0][v][j]+dp[1][u][k]+2*e[i].d)
     49                     dp[1][u][k+j]=dp[0][v][j]+dp[1][u][k]+2*e[i].d;
     50             }
     51         }
     52     }
     53 }
     54 
     55 int main()
     56 {
     57     #ifndef ONLINE_JUDGE
     58         freopen("a.in" , "r" , stdin);
     59     #endif // ONLINE_JUDGE
     60     int cas = 0;
     61     while(scanf("%d" , &n) , n)
     62     {
     63         printf("Case %d:
    " , ++cas);
     64         memset(first , -1 , sizeof(first));
     65         k = 0;
     66         for(int i=1 ; i<=n ; i++) fa[i]=i;
     67         for(int i=1 ; i<n ; i++){
     68             int u,v,d;
     69             scanf("%d%d%d" , &u , &v , &d);
     70             u++ , v++;
     71             add_edge(v , u , d);
     72             fa[u] = v;
     73         }
     74         int st;
     75         for(int i=1 ; i<=n ; i++)
     76             if(fa[i]==i) st = i;
     77 
     78         memset(dp , -1 , sizeof(dp));
     79         dfs(st);
     80         /*debug
     81         for(int i=1 ; i<=n ; i++){
     82             for(int j=1 ; j<=n ; j++){
     83                 printf("%4I64d" , dp[1][i][j]);
     84             }
     85             cout<<endl;
     86         }*/
     87         scanf("%d" , &m);
     88         for(int i=0 ; i<m ; i++){
     89             int x;
     90             scanf("%d" , &x);
     91             int ret = 0;
     92             for(int t=1 ; t<=n ; t++){
     93               //  cout<<dp[0][1][t]<<" "<<dp[1][1][t]<<endl;
     94                 if((dp[0][st][t]<=x && dp[0][st][t]>=0) || (dp[1][st][t]<=x && dp[1][st][t]>=0))
     95                     ret = max(ret , t);
     96             }
     97             printf("%d
    " , ret);
     98         }
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    pat甲级 1155 Heap Paths (30 分)
    pat甲级 1152 Google Recruitment (20 分)
    蓝桥杯 基础练习 特殊回文数
    蓝桥杯 基础练习 十进制转十六进制
    蓝桥杯 基础练习 十六进制转十进制
    蓝桥杯 基础练习 十六进制转八进制
    51nod 1347 旋转字符串
    蓝桥杯 入门训练 圆的面积
    蓝桥杯 入门训练 Fibonacci数列
    链表相关
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4537374.html
Copyright © 2011-2022 走看看