zoukankan      html  css  js  c++  java
  • HDU 5815

    题意:

      王国地图为 n 个节点的根树,首都为 1,

      m 个旅行家要去不同的终点旅游,他们分别有各自的预算,如果路上总费用超过预算就不去了

      给每条路定价, 让赚的钱最多

    分析:

        DP[i][j]表示当从首都到城市i的路径花费为j时,以i为根的子树中的点作为目的城市的旅行者的最大花费.

      只需要考虑j值等于0或等于某位旅行者预算的情况,所以dp的状态数是O(NM)的.

      状态转移方程式:

            DP[i][j] = j* n(i,j) + ∑​max(DP[k][j​i]) (ji >= j)     

        ( n(i,j)为以i作为目标城市且预算不小于j的旅行者数量,

          k 为 i 的所有子代节点

          ​max(DP[k][j​i]) 为节点k的所有ji >= j 的 DP[k][j​i] 的最大值 )

      上式max(DP[k, j​i]) (ji >= j) 可用 DP[i][j] = max(DP[i][j], DP[i][j+1]) 递推而得 则转移方程式为: DP[i][j] = j* n(i,j) + DP[i][j].

      确定完每一点的最大花费总和后,两点的最大花费总和相减即为该边的定价

      注意起点的花费一定为 0 !

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <vector>
     5 #include <algorithm>
     6 using namespace std;
     7 #define LL long long
     8 const int MAXN = 1005;
     9 int t, n, m, s;
    10 vector<int> mp[MAXN], id[MAXN];
    11 LL dp[MAXN][MAXN];
    12 LL v[MAXN];
    13 int edge[MAXN][MAXN];
    14 int bst[MAXN][MAXN];
    15 LL ans[MAXN];
    16 LL a[MAXN];
    17 void DFS(int x,int fa)
    18 {
    19     for (int i = 0; i < mp[x].size(); i++)
    20     {
    21         if (mp[x][i] != fa) DFS(mp[x][i], x);
    22     }    
    23     for (int j = s-1; j >= 0; j--)
    24     {
    25         int t = 0;
    26         for (int i = 0; i < id[x].size(); i++)
    27             if (a[id[x][i]] >= v[j]) t++;
    28         dp[x][j] += t*v[j];                         //j* n(i,j) 
    29         for (int i = 0; i < mp[x].size(); i++)
    30         {
    31             if (mp[x][i] == fa) continue;
    32             int p = mp[x][i];
    33             dp[x][j] += dp[p][j];
    34         }    
    35         if (j == s-1 || dp[x][j+1] <= dp[x][j])
    36         {
    37             bst[x][j] = j;
    38         }
    39         else
    40         {
    41             dp[x][j] = dp[x][j+1];
    42             bst[x][j] = bst[x][j+1];
    43         }
    44     }
    45 }
    46 void DFS2(int x,int a,int fa)
    47 {
    48     for (int i = 0; i < mp[x].size(); i++)
    49     {
    50         int e = mp[x][i];
    51         if (e == fa) continue;
    52         int b = bst[e][a];
    53         ans[edge[x][e]] =v[b]- v[a];
    54         DFS2(e,b,x);
    55     }
    56 }
    57 int main()
    58 {
    59     scanf("%d", &t);
    60     while (t--)
    61     {
    62         scanf("%d%d", &n, &m);
    63         for (int i = 1; i <= n; i++) mp[i].clear(), id[i].clear();
    64         memset(dp,0,sizeof(dp));
    65         for (int i = 1; i < n ;i++)
    66         {
    67             int u,v; scanf("%d%d", &u, &v);
    68             mp[u].push_back(v); 
    69             mp[v].push_back(u);
    70             edge[u][v] = edge[v][u] = i;
    71         }
    72         for (int i = 1; i <= m; i++)
    73         {
    74             int u; scanf("%d%lld",&u, &a[i]);
    75             v[i] = a[i];
    76             id[u].push_back(i);
    77         }
    78         id[1].clear();//起始点不计费!
    79         v[0] = 0;
    80         sort(v,v+1+m);
    81         s = unique(v,v+1+m) - v;
    82         DFS(1,-1);
    83         DFS2(1,0,-1);
    84         printf("%lld
    ",dp[1][0]);
    85         for (int i = 1; i < n-1; i++)
    86             printf("%lld ",ans[i]);
    87         printf("%lld
    ", ans[n-1]);
    88     }
    89 } 
    我自倾杯,君且随意
  • 相关阅读:
    Oracle一次可以查询多个表的结果的方法
    nagios+logstash实时监控java日志(一)
    原 ELK+Filebeat集中式日志解决方案(centos7)
    关于系统运维监控规范的几点建议和思考
    web文件管理系统和日志实时监控工具
    [运维]ELK实现日志监控告警
    阿里云服务器 发送邮箱 STMP 25端口 465端口问题 Javamail 25被禁用
    Elasticsearch5.6搭建及拼音中文混合搜索实现
    ELK pipeline
    图解Elasticsearch中的_source、_all、store和index属性
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5759414.html
Copyright © 2011-2022 走看看