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 }
  • 相关阅读:
    dubbo学习小计
    学习java虚拟机
    学习java虚拟机
    学习java虚拟机
    学习java虚拟机
    学习设计模式
    学习设计模式
    学习设计模式
    mybatis从入门到精通(五) sqlSession API的使用
    mybatis从入门到精通(四) 动态SQL
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4537374.html
Copyright © 2011-2022 走看看