1 Star 1 Fork 1

brealid / mycode

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
P3687.cpp 5.14 KB
一键复制 编辑 原始数据 按行查看 历史
brealid 提交于 2020-11-01 13:26 . Initial Commit
// 自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只
// 要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也
// 能够保持自己的本色走下去。 ——陈立杰
/*************************************
* @problem: P3687 [ZJOI2017]仙人掌.
* @user_id: 63720.
* @user_name: brealid.
* @time: 2020-06-02.
* @language: C++.
* @upload_place: Luogu.
*************************************/
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
typedef signed char int8;
typedef unsigned char uint8;
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
typedef unsigned uint32;
typedef long long int64;
typedef unsigned long long uint64;
template <typename Int>
inline Int read()
{
Int flag = 1;
char c = getchar();
while ((!isdigit(c)) && c != '-' && c != EOF) c = getchar();
if (c == '-') flag = -1, c = getchar();
Int init = c & 15;
while (isdigit(c = getchar())) init = (init << 3) + (init << 1) + (c & 15);
return init * flag;
}
template <typename Int>
inline Int read(char &c)
{
Int flag = 1;
c = getchar();
while ((!isdigit(c)) && c != '-' && c != EOF) c = getchar();
if (c == '-') flag = -1, c = getchar();
Int init = c & 15;
while (isdigit(c = getchar())) init = (init << 3) + (init << 1) + (c & 15);
return init * flag;
}
template <typename Int>
inline void write(Int x)
{
if (x < 0) putchar('-'), x = ~x + 1;
if (x > 9) write(x / 10);
putchar((x % 10) | 48);
}
template <typename Int>
inline void write(Int x, char nextch)
{
write(x);
putchar(nextch);
}
const int N = 5e5 + 7, M = 2e6 + 7, P = 998244353;
#define FOR_EDGES(e, x) for (int e = head[x]; ~e; e = nxt[e])
#define ADD_EDGE(u, v) { to[cnt] = v; nxt[cnt] = head[u]; head[u] = cnt++; }
#define MEM_ARR(arr, siz, v) { for (unsigned i = 0; i < siz + 5; i++) arr[i] = v; }
#define FA(u) (to[fae[u] ^ 1])
inline int Module(int w) { return w >= P ? w - P : w; }
int mul(int x) { return x; }
template<typename... Type>
int mul(int x, Type... Args) { return (int64)x * mul(Args...) % P; }
int add(int x) { return x; }
template<typename... Type>
int add(int x, Type... Args) { return Module(x + add(Args...)); }
template<typename T>
void memarr(size_t siz, int val, T Arg) { MEM_ARR(Arg, siz, val); }
template<typename T, typename... T_>
void memarr(size_t siz, int val, T FirstArg, T_... Args) {
MEM_ARR(FirstArg, siz, val);
memarr(siz, val, Args...);
}
int T, n, m;
int to[M], nxt[M], head[N], cnt;
int tag[M];
bool vis[N];
int cover[N];
int fae[N], fa[N], dep[N];
int h[N], g[N];
bool makeTag(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
while (dep[u] > dep[v]) {
if (tag[fae[u] >> 1]) return true;
tag[fae[u] >> 1] = true;
u = fa[u];
}
while (u != v) {
if (tag[fae[u] >> 1]) return true;
tag[fae[u] >> 1] = true;
u = fa[u];
if (tag[fae[v] >> 1]) return true;
tag[fae[v] >> 1] = true;
v = fa[v];
}
return false;
}
bool dfs(int u, int faE) {
fae[u] = faE;
fa[u] = FA(u);
dep[u] = dep[fa[u]] + 1;
vis[u] = true;
FOR_EDGES(e, u) {
int v = to[e];
if (v != fa[u]) {
if (vis[v]) {
if (!tag[e >> 1]) {
tag[e >> 1] = true;
if (makeTag(u, v)) return true;
}
} else {
if (dfs(v, e)) return true;
}
}
}
return false;
}
void solve(int u) {
vis[u] = true;
int deg = 0;
FOR_EDGES(e, u) {
int v = to[e];
if (v && !vis[v] && !tag[e >> 1]) { // 特判虚拟节点 0
solve(v);
g[u] = mul(g[u], g[v]);
deg++;
}
}
g[u] = mul(h[deg + 1], g[u]);
}
int getAns(int u) {
int res = 1, deg = 0;
FOR_EDGES(e, u) {
int v = to[e];
if (v && !tag[e >> 1]) { // 特判虚拟节点 0
res = mul(res, g[v]);
deg++;
}
}
return mul(res, h[deg]);
}
int main()
{
T = read<int>();
h[0] = h[1] = 1;
for (int i = 2; i <= N - 5; i++) h[i] = add(h[i - 1], mul(i - 1, h[i - 2]));
while (T--) {
n = read<int>();
m = read<int>();
cnt = 0;
memarr(n, -1, head);
memarr(n, 0, cover, vis);
memarr(n, 1, g);
memarr(m, 0, tag);
ADD_EDGE(0, 1);
ADD_EDGE(1, 0); // 建立虚拟节点 0 作为节点 1 的父亲节点,防止 dfs(1, 0) 时调用边出错。
for (int i = 1, u, v; i <= m; i++) {
u = read<int>();
v = read<int>();
ADD_EDGE(u, v);
ADD_EDGE(v, u);
}
if (dfs(1, 0)) {
puts("0");
continue;
}
memarr(n, 0, vis);
int ans = 1;
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
solve(i);
ans = mul(ans, getAns(i));
}
}
write(ans, 10);
}
return 0;
}
C++
1
https://gitee.com/hkxa/mycode.git
git@gitee.com:hkxa/mycode.git
hkxa
mycode
mycode
master

搜索帮助