• 洛谷 题解 P1351 【联合权值】


    Problem

    P1351 【联合权值】

    record

    • 用时: 99ms
    • 空间: 13068KB(12.76MB)
    • 代码长度: 3.96KB
    • 提交记录: R9883701
    • 注: 使用了
      1. o1 优化
      2. o2 优化
      3. o3 优化
      4. use-v4
      5. 快读快输

    Solution

    60 or 70 pts

    直接爆搜,枚举每两个距离为 2 的点,然后记录答案。

    写法优异可以拿走 70 pts , 但是 use-v4 几乎铁定是 60 pts 。

    代码。。。就不放了,有兴趣的可以看:

    60 pts (use-v4)

    70 pts (use-v3)

    70100 pts

    考虑我们的思路慢在哪儿?

    在于组合!

    考虑一个菊花图,复杂度几乎是 Θ(n^2) 的,当然慢。

    想到乘法交换律(数学老师不要怪我这么长时间才想起你)

    这时候考虑任意两个距离为 2 的有序点对一定会有一个中间点,枚举这个点即可,并不需要搜索。复杂度 Θ(n)Θ(n) ,菊花图不会卡

    100 pts

    思路基本没什么问题了吧!

    等等,图 G 上联合权值的最大值呢?

    每次记录中间点相邻点中最大的和次大的即可。

    没问题了吧?

    不,还有问题!

    答案要乘 2 !

    因为题目可以看成一对有序点对要计算两次。

    Code

      1 // luogu-judger-enable-o2
      2 /*
      3     Problem:    P1351 联合权值 
      4     Author:     航空信奥 
      5     Date:       2018/08/18
      6     Upload:     Luogu
      7     P.s.:       use-v4
      8 */
      9 #pragma GCC optimize("O1")
     10 #pragma GCC optimize("O2")
     11 #pragma GCC optimize("O3")
     12 #include <stdio.h>
     13 #include <string.h>
     14 #include <vector>
     15 using namespace std;
     16 
     17 namespace AuthorName { /* 防重名 */
     18     template <typename _TpInt> inline _TpInt read();
     19     template <typename _TpInt> inline void write(_TpInt x);
     20 
     21 #   define Online_Judge
     22 #   define Max_N 200007
     23 #   define Mod 10007
     24 
     25     vector<vector<int> > g;
     26     int *w;
     27     int maxx = 0, sum = 0;
     28 
     29     void work(int p)
     30     {
     31         int max_1st = 0, max_2nd = 0, temp_sum = 0;
     32         for (size_t i = 0; i < g[p].size(); i++) {
     33             if (w[g[p][i]] > max_1st) {
     34                 max_2nd = max_1st;
     35                 max_1st = w[g[p][i]];
     36             }
     37             else if (w[g[p][i]] > max_2nd) {
     38                 max_2nd = w[g[p][i]];
     39             }
     40             sum = (sum + temp_sum * w[g[p][i]]) % Mod;
     41             temp_sum = (temp_sum + w[g[p][i]]) % Mod;
     42         }
     43         maxx = max(maxx, max_1st * max_2nd);
     44     } 
     45 
     46     int main() 
     47     {   
     48         int n;
     49         n = read<int>();
     50         g.resize(n + 1);
     51         w = new int[n + 1];
     52         int u, v;
     53         for (int i = 1; i < n; i++) {
     54             u = read<int>();
     55             v = read<int>();
     56             g[u].push_back(v);
     57             g[v].push_back(u);
     58         }
     59         for (int i = 1; i <= n; i++) {
     60             w[i] = read<int>();
     61         }
     62         for (int i = 1; i <= n; i++) {
     63             work(i);
     64         }
     65 
     66         write(maxx), putchar(32), write((sum << 1) % Mod), putchar(10);
     67 
     68         return 0;
     69     }
     70 
     71 #ifdef Online_Judge
     72     char BufferRead[1 << 15];
     73     int rLen = 0, rPos = 0;
     74     inline char Getchar()
     75     {
     76         if (rPos == rLen) rPos = 0, rLen = fread(BufferRead, 1, 1 << 15, stdin);
     77         if (rPos == rLen) return EOF;
     78         return BufferRead[rPos++];
     79     } 
     80 #else
     81 #   define Getchar() getchar()
     82 #endif
     83 
     84     template <typename _TpInt>
     85     inline _TpInt read()       
     86     {
     87         register int flag = 1;
     88         register char c = Getchar();
     89         while ((c > '9' || c < '0') && c != '-') 
     90             c = Getchar();
     91         if (c == '-') flag = -1, c = Getchar();
     92         register _TpInt init = (c & 15);
     93         while ((c = Getchar()) <= '9' && c >= '0') 
     94             init = (init << 3) + (init << 1) + (c & 15);
     95         return init * flag;
     96     }
     97 
     98     template <typename _TpInt>
     99     inline void write(_TpInt x)
    100     {
    101         if (x < 0) {
    102             putchar('-');
    103             write<_TpInt>(~x + 1);
    104         }
    105         else {
    106             if (x > 9) write<_TpInt>(x / 10);   
    107             putchar(x % 10 + '0');
    108         }
    109     }
    110 }
    111 
    112 int main()
    113 {
    114     AuthorName::main();
    115     return 0;
    116 }
    View Code
  • 相关阅读:
    子组 正则表达式
    正则表达式
    马云北大演讲完整版:真心话,什么才是阿里的核心竞争力?-2014-03-20
    形象化的spring 依赖注入原理
    程序员的六层境界
    apache配置运行zendframework 2
    php编写简单的页面跳转功能
    php随机验证码
    没啥说的
    PHP流程控制语句下
  • 原文地址:https://www.cnblogs.com/hkxadpall/p/9497947.html
Copyright © 2020-2023  润新知