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


    Problem

    P1351 【联合权值】

    record

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

    Solution

    (60 ext{ or } 70 ext{pts})

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

    写法优异可以拿走 (70 ext{pts}) , 但是 use-v4 几乎铁定是 (60 ext{pts})

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

    (60 ext{pts}) (use-v4)

    (70 ext{pts}) (use-v3)

    $ 70Rightarrow 100 ext{pts}$

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

    在于组合!

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

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

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

    (100 ext{pts})

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

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

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

    没问题了吧?

    不,还有问题!

    答案要乘 2 !

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

    Code

    // luogu-judger-enable-o2
    /*
        Problem:	P1351 联合权值 
        Author:		航空信奥 
        Date:		2018/08/18
        Upload:		Luogu
        P.s.:		use-v4
    */
    #pragma GCC optimize("O1")
    #pragma GCC optimize("O2")
    #pragma GCC optimize("O3")
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    using namespace std;
    
    namespace AuthorName { /* 防重名 */
        template <typename _TpInt> inline _TpInt read();
        template <typename _TpInt> inline void write(_TpInt x);
        
    #	define Online_Judge
    #	define Max_N 200007
    #	define Mod 10007
        
        vector<vector<int> > g;
        int *w;
        int maxx = 0, sum = 0;
        
        void work(int p)
        {
            int max_1st = 0, max_2nd = 0, temp_sum = 0;
            for (size_t i = 0; i < g[p].size(); i++) {
                if (w[g[p][i]] > max_1st) {
                    max_2nd = max_1st;
                    max_1st = w[g[p][i]];
                }
                else if (w[g[p][i]] > max_2nd) {
                    max_2nd = w[g[p][i]];
                }
                sum = (sum + temp_sum * w[g[p][i]]) % Mod;
                temp_sum = (temp_sum + w[g[p][i]]) % Mod;
            }
            maxx = max(maxx, max_1st * max_2nd);
        } 
        
        int main() 
        {	
            int n;
            n = read<int>();
            g.resize(n + 1);
            w = new int[n + 1];
            int u, v;
            for (int i = 1; i < n; i++) {
                u = read<int>();
                v = read<int>();
                g[u].push_back(v);
                g[v].push_back(u);
            }
            for (int i = 1; i <= n; i++) {
                w[i] = read<int>();
            }
            for (int i = 1; i <= n; i++) {
                work(i);
            }
            
            write(maxx), putchar(32), write((sum << 1) % Mod), putchar(10);
            
            return 0;
        }
        
    
    #ifdef Online_Judge
        char BufferRead[1 << 15];
        int rLen = 0, rPos = 0;
        inline char Getchar()
        {
            if (rPos == rLen) rPos = 0, rLen = fread(BufferRead, 1, 1 << 15, stdin);
            if (rPos == rLen) return EOF;
            return BufferRead[rPos++];
        } 
    #else
    #	define Getchar() getchar()
    #endif
    
        template <typename _TpInt>
        inline _TpInt read()       
        {
            register int flag = 1;
            register char c = Getchar();
            while ((c > '9' || c < '0') && c != '-') 
                c = Getchar();
            if (c == '-') flag = -1, c = Getchar();
            register _TpInt init = (c & 15);
            while ((c = Getchar()) <= '9' && c >= '0') 
                init = (init << 3) + (init << 1) + (c & 15);
            return init * flag;
        }
    
        template <typename _TpInt>
        inline void write(_TpInt x)
        {
            if (x < 0) {
                putchar('-');
                write<_TpInt>(~x + 1);
            }
            else {
                if (x > 9) write<_TpInt>(x / 10);   
                putchar(x % 10 + '0');
            }
        }
    }
    
    int main()
    {
        AuthorName::main();
        return 0;
    }
    
  • 相关阅读:
    [LeetCode] 1131. Maximum of Absolute Value Expression 绝对值表达式的最大值
    [LeetCode] 1130. Minimum Cost Tree From Leaf Values 叶值的最小代价生成树
    [LeetCode] 1129. Shortest Path with Alternating Colors 颜色交替的最短路径
    [LeetCode] 1128. Number of Equivalent Domino Pairs 等价多米诺骨牌对的数量
    [LeetCode] 1125. Smallest Sufficient Team 最小的必要团队
    [LeetCode] 1124. Longest Well-Performing Interval 表现良好的最长时间段
    [LeetCode] 1122. Relative Sort Array 数组的相对排序
    Gitalk 自动初始化评论
    [LeetCode] 1111. Maximum Nesting Depth of Two Valid Parentheses Strings 有效括号的嵌套深度
    [LeetCode] 1110. Delete Nodes And Return Forest 删点成林
  • 原文地址:https://www.cnblogs.com/hkxadpall/p/9895942.html
Copyright © 2020-2023  润新知