D. Triangle Coloring
D. Triangle Coloring
You are given an undirected graph consisting of vertices and edges, where is divisible by . Each edge has a weight, which is a positive (greater than zero) integer.
The graph has the following structure: it is split into triples of vertices, the first triple consisting of vertices , the second triple consisting of vertices , and so on. Every pair of vertices from the same triple is connected by an edge. There are no edges between vertices from different triples.
You have to paint the vertices of this graph into two colors, red and blue. Each vertex should have exactly one color, there should be exactly red vertices and blue vertices. The coloring is called valid if it meets these constraints.
The weight of the coloring is the sum of weights of edges connecting two vertices with different colors.
Let be the maximum possible weight of a valid coloring. Calculate the number of valid colorings with weight , and print it modulo .
Input
The first line contains one integer (, is divisible by ).
The second line contains integers () — the weights of the edges. Edge connects vertices and , edge connects vertices and , edge connects vertices and , edge connects vertices and , edge connects vertices and , edge connects vertices and , and so on.
Output
Print one integer — the number of valid colorings with maximum possible weight, taken modulo .
Examples
input
12 1 3 3 7 8 5 2 2 2 2 4 2
output
36
input
6 4 2 6 6 6 4
output
2
Note
The following picture describes the graph from the first example test.
The maximum possible weight of a valid coloring of this graph is .
解题思路
先考虑最大价值是多少。对于一个三元图,很明显通过染色最多只能选择条边,如下图:
因此为了获得最大价值,每一个三元图都应该选择权值最大的两条边,对应的染色方案是这两条边共同的节点染红色(蓝色),另外两个节点染蓝色(红色)。
由于共有个三元图,,那么有,因此如果一个三元图为红蓝,那么必然会存在另外一个三元图是蓝红(参考上图中上下两个三元图)。因此整个图中会有个三元图为红蓝,有个三元图为蓝红。因此从整体上来看,就有种染色方案(从个三元图中选择个染成红蓝)。
再考虑每个三元图本身,很明显如果条边的权值都相同,那么它本身就有种染色方案。如果权值最小的边有两条(比如),那么就有种染色方案。其余的情况就只有一种染色方案,即选择最大边长和次大边长。记每个三元图本身的染色方案为。
因此根据乘法原理,总的获得最大价值的染色方案为。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int mod = 998244353; 7 8 int qmi(int a, int k) { 9 int ret = 1; 10 while (k) { 11 if (k & 1) ret = 1ll * ret * a % mod; 12 a = 1ll * a * a % mod; 13 k >>= 1; 14 } 15 return ret; 16 } 17 18 int C(int a, int b) { 19 int ret = 1; 20 for (int i = 1, j = a; i <= b; i++, j--) { 21 ret = 1ll * ret * j % mod * qmi(i, mod - 2) % mod; 22 } 23 return ret; 24 } 25 26 int main() { 27 int n; 28 scanf("%d", &n); 29 int ret = C(n / 3, n / 6); 30 for (int i = 0; i < n; i += 3) { 31 int a[3]; 32 for (int j = 0; j < 3; j++) { 33 scanf("%d", a + j); 34 } 35 sort(a, a + 3); 36 if (a[0] == a[2] && a[1] == a[2]) ret = 3ll * ret % mod; // 3条边的权值相等 37 else if (a[0] == a[1]) ret = 2ll * ret % mod; // 否则3条边的权值不完全相等,而最小的两条边相等 38 } 39 printf("%d", ret); 40 41 return 0; 42 }
参考资料
Educational Codeforces Round 143 D(组合数学):https://zhuanlan.zhihu.com/p/607034527
Educational Codeforces Round 143 Editorial:https://codeforces.com/blog/entry/112963
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17132913.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-02-18 地宫取宝