首页 > 其他分享 >[ARC062F] AtCoDeerくんとグラフ色塗り 题解

[ARC062F] AtCoDeerくんとグラフ色塗り 题解

时间:2024-09-25 20:35:35浏览次数:1  
标签:dn 色塗 210 ARC062F int 题解 back lw ot

思路

对于一个点双,我们可以发现:

  1. 假如它是一个简单环,那么它只能旋转这一个环,我们可以使用 polya 定理计算。
  2. 假如它是多个环的组成,那么它的颜色可以随意调动,任何的情况都可以得到,那么假如说有 \(m\) 条边,方案数则为 \(\binom{m+k-1}{k-1}\),我们只考虑每一种颜色的出现次数。

对于其他的边,都可以随意染色。

那么我们直接提出所有点双,统计方案即可。

Code

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int mod = 1e9 + 7;

int n, m, k, tp, tt, ct, ans = 1;
int p[210], dn[210], lw[210], st[210], vs[210];
int c[210][210];
vector<int> to[210];
vector<int> ot[210];

inline void tarjan(int x, int fa) {
  dn[x] = lw[x] = ++tt, st[++tp] = x;
  for (auto i : to[x]) if (i != fa) {
    if (!dn[i]) {
      tarjan(i, x);
      lw[x] = min(lw[x], lw[i]);
      if (lw[i] >= dn[x]) {
        ot[++ct].push_back(x);
        while (ot[ct].back() != i) ot[ct].push_back(st[tp--]);
      }
    } else lw[x] = min(lw[x], dn[i]);
  }
}
inline int sol(int x) {
  int r = 0;
  for (int i = 1; i <= x; i++) r = (r + p[__gcd(i, x)]) % mod;
  while (r % x != 0) r += mod;
  return r / x % mod;
}

signed main() {
  for (int i = 0; i <= 200; i++) c[i][0] = 1;
  for (int i = 1; i <= 200; i++)
    for (int j = 1; j <= i; j++)
      c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
  cin >> n >> m >> k;
  p[0] = 1;
  for (int i = 1; i <= m; i++) p[i] = p[i - 1] * k % mod;
  for (int i = 1, u, v; i <= m; i++) {
    cin >> u >> v;
    to[u].push_back(v);
    to[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) if (!dn[i]) tarjan(i, 0);
  for (int i = 1; i <= ct; i++) {
    int ps = 0;
    for (auto j : ot[i]) vs[j] = 1;
    for (auto j : ot[i]) for (auto k : to[j]) ps += vs[k];
    for (auto j : ot[i]) vs[j] = 0;
    ps = ps / 2;
    if (ps == ot[i].size()) ans = ans * sol(ps) % mod;
    else if (ps < ot[i].size()) ans = ans * p[ps] % mod;
    else if (ps > ot[i].size()) ans = ans * c[ps + k - 1][k - 1] % mod;
  }
  cout << ans << "\n";
}

标签:dn,色塗,210,ARC062F,int,题解,back,lw,ot
From: https://www.cnblogs.com/JiaY19/p/18432132

相关文章

  • 题解 QOJ5034【>.<】/ BC2401D【可爱路径】
    必可赛前公益众筹赛第一试Dhttps://qoj.ac/problem/5034,2022-2023集训队互测Round6(Nov12,2022)题目描述这原本是一道简单的最短路问题,但是由于种种地域文化,宗教信仰以及政治因素,原来一些或许可以行走的路径不能通行了。我们定义禁止路径为连续的经过一些特定的点的......
  • Luogu_P10977(AcWing_299) Cut the Sequence 题解
    解题思路考虑线性dp。首先如果存在\(a_i>m\),那肯定不满足条件,输出\(-1\)。设\(f_i\)表示前\(i\)个数分成若干段,然后每段最大数之和,其中每段内的整数之和不超过\(m\)。\(f_i\)肯定是由\(f_j\)(\(1\lej<i\))转移过来的,也就是前\(j\)个数分好后再加上\((j,i]\)这一......
  • 【OJ题解-1】稀疏矩阵乘法
    一、试题题面计算两个稀疏矩阵相乘,输出相乘的结果【输入输出约定】输入:第一行输入三个正整数p、q、r,表示p×q和q×r的两个矩阵相乘;(约定0<p,q,r≤1000)然后是第一个矩阵的输入,首先是一个整数m,表示矩阵一有m个非零元素;然后是m行,每行三个整数i,j,d,表示第i行,第j列的元素为d(约定......
  • P8906 [USACO22DEC] Breakdown P 题解
    P8906[USACO22DEC]BreakdownP题解显然的套路是删边转化为加边。考虑到维护整条路径不好维护,于是考虑转化维护\(f_{i,k},g_{i,k}\)分别表示\(1,n\)到\(i\)走了\(k\)步时的最短路。那么此时\(k\le4\)。我们先考虑\(f\)的转移,\(g\)的转移是等价的。那么对于\((......
  • 题解:CF573D Bear and Cavalry
    因为这是远古题目,所以根据现在的评测机速度,用\(O(nq)\)的做法也是可以过的。也就是说,我们可以每次操作直接修改对应位置上的数字,然后设计一种\(O(n)\)的算法求解答案。这道题类似资源分配型动态规划,所以我们可以设\(dp_i\)表示分配前\(i\)个人的答案。直接写是不行的,我......
  • 题解:AT_abc204_e [ABC204E] Rush Hour 2
    变形的dijkstra。先思考什么情况下需要等待以及等待多长时间最优。我们把题目上的计算方法按照当前的时间\(t\)和通过所需的时间\(f(t)\)列个函数关系:\[f(t)=t+c+\lfloor\frac{d}{t+1}\rfloor\]然后用Desmos画个图可以得到图像(其实就是对勾函数):因为\(c,d\geq0\),所......
  • [湖北省选模拟 2023] 棋圣 / alphago 题解
    很牛的题目啊。-Alex_Wei发现这个操作比较复杂但限制较弱,考虑通过考察“不变的量”来刻画操作。容易发现若为二分图,则初始颜色不同的一定不能移动到一起。又因为在存在环的图上这个限制很弱/目前较难考虑,所以先考虑树的情况,发现答案存在可能取到的上界,令\(c_{i,j}\)为初......
  • CF1119H Triple 题解
    DescriptionSK酱送给你了一份生日礼物。礼物是\(n\)个三元组\((a_i,b_i,c_i)\)和四个正整数\(x,y,z,k\)。你利用这\(n\)个三元组填充了\(n\)个数组,其中第\(i\)个数组中有\(x\)个\(a_i\),\(y\)个\(b_i\),\(z\)个\(c_i\)(所以第\(i\)个数组长度为\((x+y+z)\)。......
  • Codeforces Round 974 (Div. 3)题解记录
    A.RobinHelps签到模拟,遍历一遍即可,注意没钱时不给钱。\(O(n)\)#include<iostream>#include<set>#include<map>#include<vector>#include<algorithm>#include<bitset>#include<math.h>#include<string>#include<string.h>#......
  • [ARC122E] Increasing LCMs 题解
    感觉像比较套路的构造题。思路假如我们正着进行构造,可以发现我们加入一个数以后,对后面的数产生的影响是很大的。但是如果我们从最后一个数开始构造,那么可以发现它是不会对之后的构造产生任何影响的。应为越前面的数的限制会越少,那么可以填的数一定是不减的。一个数可以填在后......