首先,我们需要给一个连通块找到一个直观的合法判定解。

那么我们必须以一种直观的方式将边按照权值分开,这样才能直观地判定一个合法的组。

一个常见的方式是将边从小到大依次加入进来,那么在任意时刻图上存在的边和不存在的边就恰好被一个权值分开了。

那么我们可以很清晰地发现,一个联通块是合法的,当且仅当在上述流程的某个时刻这个连通块会形成一个团。

于是此时一个很暴力的做法就是预处理出所有合法的连通块,然后状压 \(dp\),但这样是指数级的,显然不可取。

看似这个问题已经难以优化了,但你会发现上面这个依次加边的模型非常类似于 \(\rm Kruskal\) 重构树,那么这个 \(dp\) 可不可以在重构树上被优化呢?

那么你会发现上面的这个团只可能是 \(\rm Kruskal\) 重构树上的一颗子树或一个单点,同时这些团也可以在 \(\rm Kruskal\) 的流程中求出。

于是问题就转化为给定一棵树,你需要把这颗树划分成 \(k\) 个联通块,每个可划分的联通块都是给定的的方案。

不难发现这个东西可以直接树形背包 \(O(n ^ 2)\) 解决。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define Next(i, u) for (int i = h[u]; i; i = e[i].next)
const int N = 3000 + 5;
const int M = 1500 + 5;
const int Mod = 998244353;
struct edge { int v, next;} e[N << 1];
int n, tot, cnt, d[N], h[N], sz[N], fa[N], x[M * M], y[M * M], a[M][M], dp[N][M];
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int Inc(int a, int b) { return (a += b) >= Mod ? a - Mod : a;}
int Mul(int a, int b) { return 1ll * a * b % Mod;}
int find(int x) { return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);}
void add(int u, int v) {
e[++tot].v = v, e[tot].next = h[u], h[u] = tot;
e[++tot].v = u, e[tot].next = h[v], h[v] = tot;
}
void dfs(int u, int fa) {
int a = 0, b = 0;
Next(i, u) {
int v = e[i].v; if(v == fa) continue;
dfs(v, u); if(!a) a = v; else b = v;
}
rep(i, 1, sz[a]) rep(j, 1, sz[b]) dp[u][i + j] = Inc(dp[u][i + j], Mul(dp[a][i], dp[b][j]));
if(d[u] == sz[u] * (sz[u] - 1) / 2) dp[u][1] = 1;
}
int main() {
n = cnt = read();
rep(i, 1, n) rep(j, 1, n) a[i][j] = read(), x[a[i][j]] = i, y[a[i][j]] = j;
rep(i, 1, 2 * n) fa[i] = i, sz[i] = (i <= n);
rep(i, 1, n * (n - 1) / 2) {
int Fx = find(x[i]), Fy = find(y[i]);
if(Fx != Fy) {
d[++cnt] = d[Fx] + d[Fy] + 1, sz[cnt] = sz[Fx] + sz[Fy];
fa[Fx] = fa[Fy] = cnt, add(cnt, Fx), add(cnt, Fy);
}
else ++d[Fx];
}
dfs(cnt, 0);
rep(i, 1, n) printf("%d ", dp[cnt][i]);
return 0;
}

值得一提的是,当我们的做法与某个算法流程本质相同时,可以尝试在这个算法的基础上对我们的做法进行优化。

CF1408G Clusterization Counting的更多相关文章

  1. CodeForces 1408G Clusterization Counting

    题意 给定 \(n\) 个点的无向带权完全图,边权为 \(1\sim\frac{n(n-1)}{2}\).对于满足 \(1\leq k\leq n\) 的每个 \(k\) 求出将原图划分成 \(k\) ...

  2. Solution -「CF 1480G」Clusterization Counting

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 阶完全图,边权为 \(1\sim\frac{n(n-1)}2\) 的排列.称一种将点集划分为 \(k\) ...

  3. 萌新笔记——Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

  4. POJ_2386 Lake Counting (dfs 错了一个负号找了一上午)

    来之不易的2017第一发ac http://poj.org/problem?id=2386 Lake Counting Time Limit: 1000MS   Memory Limit: 65536 ...

  5. ZOJ3944 People Counting ZOJ3939 The Lucky Week (模拟)

    ZOJ3944 People Counting ZOJ3939 The Lucky Week 1.PeopleConting 题意:照片上有很多个人,用矩阵里的字符表示.一个人如下: .O. /|\ ...

  6. find out the neighbouring max D_value by counting sort in stack

    #include <stdio.h> #include <malloc.h> #define MAX_STACK 10 ; // define the node of stac ...

  7. 1004. Counting Leaves (30)

    1004. Counting Leaves (30)   A family hierarchy is usually presented by a pedigree tree. Your job is ...

  8. 6.Counting Point Mutations

    Problem Figure 2. The Hamming distance between these two strings is 7. Mismatched symbols are colore ...

  9. 1.Counting DNA Nucleotides

    Problem A string is simply an ordered collection of symbols selected from some alphabet and formed i ...

随机推荐

  1. Service有多个实现类,它怎么知道该注入哪个ServiceImpl类

    方法一:Controller中注入service的时候使用@Autowired自动注入,@Qualifier("beanId")来指定注入哪一个. 方法二:Controller中注 ...

  2. Dynamic Routing Between Capsules

    目录 概 主要内容 损失函数 代码 Sabour S, Frosst N, Hinton G E, et al. Dynamic Routing Between Capsules[C]. neural ...

  3. JSP的数据从数据库中获取导入type=date的input标签中

    jsp 页面最开始加上 <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> & ...

  4. golang mongodb 驱动二次封装

    mongodb 官方的go驱动包 go.mongodb.org/mongo-driver 使用起来比较繁琐,最近对其进行了二次封装 github地址:https://github.com/w3liu/ ...

  5. pytest 一个测试类怎样使用多种fixture前置方法

    fixture()方法写在哪里? @pytest.fixture(scope="范围")写在conftest文件中,如下图 怎么使用fixture()呢?分为一个类中使用一个前置或 ...

  6. Python常用功能函数系列总结(四)之数据库操作

    本节目录 常用函数一:redis操作 常用函数二:mongodb操作 常用函数三:数据库连接池操作 常用函数四:pandas连接数据库 常用函数五:异步连接数据库 常用函数一:redis操作 # -* ...

  7. 友善之臂mini2440光盘资料下载FriendlyARM-2440-DVD.7z

    这是我目前找到最全面的友善之臂mini2440的光盘资料了,几乎支持mini2440的各种lcd屏幕.另外,Windows平台工具文件夹下还有版本比较新的MiniTools,这是一个非常好用的软件! ...

  8. Typora+PicGo-Core实现图片自动上传gitee图床

    说明: 使用gitee作为图床: 客户机为Mac M1: Typora版本:1.0.2 (5990). gitee配置步骤 需要拥有一个gitee账号,创建一个公有仓库用于存储图片,然后需要生成一个t ...

  9. MASA Framework - EventBus设计

    目录 MASA Framework - 整体设计思路 MASA Framework - EventBus设计 概述 利用发布订阅模式来解耦不同架构层级,亦可用于解决隔离业务之间的交互 优点: 松耦合 ...

  10. java下拉框转换公共方法

    1. 下拉框实例类 import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang3.Boolean ...