cf1293EE.Xenon's Attack on the Gangs(dp)

Posted heyuhhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf1293EE.Xenon's Attack on the Gangs(dp)相关的知识,希望对你有一定的参考价值。

传送门

题意:
给出一颗树,树上随机分配(0)(n-1)的边权,不存在权值相同的两条边。
定义(mex(u,v))为:树上(u)(v)的简单路径中所有边权的(mex)

[ sum_{1leq uleq vleq n}mex(u,v) ]

思路:

  • 将问题转化为求一条边的贡献,显然一条边对跨过这条边的所有点对有贡献;
  • 多条边时,只有链的形式才会增加贡献,可以不用考虑具体的权值分配;
  • 因为数据范围只有(3000),考虑枚举每条链进行(dp)
  • 记忆化搜索,保证复杂度为(O(n^2))

细节见代码:

/*
 * Author:  heyuhhh
 * Created Time:  2020/1/25 12:09:26
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 3000 + 5;

vector <int> G[N];

int n;
ll dp[N][N];
int cnt[N][N], fa[N][N];

void dfs(int u, int f, int rt) {
    cnt[rt][u] = 1;
    fa[rt][u] = f;
    for(auto v : G[u]) if(v != f) {
        dfs(v, u, rt);
        cnt[rt][u] += cnt[rt][v];
    }   
}

ll solve(int x, int y) {
    if(x == y) return 0;
    if(dp[x][y] != -1) return dp[x][y];
    dp[x][y] = cnt[y][x] * cnt[x][y] + max(solve(x, fa[x][y]), solve(y, fa[y][x]));
    return dp[x][y];   
}

void run(){
    memset(dp, -1, sizeof(dp));
    for(int i = 1; i < n; i++) {
        int u, v; cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i = 1; i <= n; i++) {
        dfs(i, 0, i);
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            ans = max(ans, solve(i, j));
        }
    }
    cout << ans << '
';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

以上是关于cf1293EE.Xenon's Attack on the Gangs(dp)的主要内容,如果未能解决你的问题,请参考以下文章

CF1293C - NEKO's Maze Game 分块

CF1293E-Xenon's Attack on the Gangs 树状DP

CF1293A - ConneR and the A.R.C. Markland-N 二分

N - Aroma's Search CodeForces - 1293D

CF1293B - JOE is on TV! DP 序列DP 单调性优化

「CF80A」Panoramix's Prediction