数据结构算法(树的比边权乘积=k)
Title
CodeForces 1401 D. Maximum Distributed Tree
Time Limit
2 seconds
Memory Limit
256 megabytes
Problem Description
You are given a tree that consists of nodes. You should label each of its edges with an integer in such way that satisfies the following conditions:
Let’s define as the sum of the numbers on the simple path from node to node . Also, let be a distribution index of the tree.
Find the maximum possible distribution index you can get. Since answer can be too large, print it modulo .
In this problem, since the number can be large, the result of the prime factorization of is given instead.
Input
The first line contains one integer () — the number of test cases.
The first line of each test case contains a single integer () — the number of nodes in the tree.
Each of the next lines describes an edge: the -th line contains two integers and (; ) — indices of vertices connected by the -th edge.
Next line contains a single integer () — the number of prime factors of .
Next line contains prime numbers () such that .
It is guaranteed that the sum of over all test cases doesn’t exceed , the sum of over all test cases doesn’t exceed , and the given edges for each test cases form a tree.
Output
Print the maximum distribution index you can get. Since answer can be too large, print it modulo .
Sample Input
3 4 1 2 2 3 3 4 2 2 2 4 3 4 1 3 3 2 2 3 2 7 6 1 2 3 4 6 7 3 5 1 3 6 4 7 5 13 3
Sample Onput
17 18 286
Note
In the first test case, one of the optimal ways is on the following image:
In this case, , , , , , , so the sum of these numbers is .
In the second test case, one of the optimal ways is on the following image:
In this case, , , , , , , so the sum of these numbers is .
Source
CodeForces 1401 D. Maximum Distributed Tree
题意
给一棵树 你可以任意分配边权
但要使得所有边权乘积
k是按质因子形式给出
设是与路径边权和。
要使得所有点对边权和最大。
思路
经典所有点对边权和,对每条边来说贡献就是左边点的个数*右边点的个数。
求出来排个序。
对于来说
如果他的质因子个数不足则补即可
如果超过呢?
则思考两两乘起来合并
是大的两两合并更优(粗略证明
设质因子为
边数贡献为
均从大到小排序
则
则合并即可
最后对应相乘就是答案,别忘了取模
AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int maxn = 3e5 + 5; const ll inf = 0x3f3f3f3f; const ll mod = 1e9 + 7; #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() void dfs(int now, int fa, vector<vector<int>> &edge, vector<ll> &c, vector<ll> &sz, int n) { sz[now] = 1; for (auto &it : edge[now]) { if (it == fa) continue; dfs(it, now, edge, c, sz, n); sz[now] += sz[it]; } c.emplace_back(sz[now] * (n - sz[now])); } int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int T; cin >> T; while (T--) { int n; cin >> n; vector<vector<int>> edge(n + 1, vector<int>()); for (int i = 1, u, v; i < n; ++i) { cin >> u >> v; edge[u].emplace_back(v); edge[v].emplace_back(u); } int m; cin >> m; deque<ll> dq(m); for (auto &it : dq) cin >> it; sort(all(dq), greater<ll>()); while (dq.size() > n - 1) { dq[1] = dq[0] * dq[1] % mod; dq.pop_front(); } while (dq.size() < n - 1) dq.push_back(1); vector<ll> c, sz(n + 1); dfs(1, 0, edge, c, sz, n); sort(all(c), greater<ll>()); ll ans = 0; for (int i = 0; i < n - 1; ++i) { ans = (ans + c[i] * dq[i] % mod) % mod; } cout << ans << endl; } return 0; }
本文地址:https://blog.csdn.net/weixin_44354699/article/details/108162921
上一篇: Android 10(Q)/11(R) 分区存储适配
下一篇: keep-alive标签的作用