noip模拟赛 少女
2017-11-01 15:02
387 查看
分析:每个连通块都是独立的,对一个连通块进行分析.如果边数>点数,显然是不可能的,因为每条边要分配给一个点,至少有一个点分配了两次以上.如果边数=点数,就形成了环,有两种方案,顺时针一个环,逆时针一个环.如果边数=点数-1,形成了链,将n个点分配n-1条边,答案为C(n,n-1),也就是n,统计一下每个连通块有多少个点,多少条边就可以了.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 200010, mod = 1e9 + 7; int n, m, cnt1, cnt2, head[maxn], to[maxn], nextt[maxn], tot = 1; bool vis[maxn], vis2[maxn]; long long ans = 0; void add(int x, int y) { to[tot] = y; nextt[tot] = head[x]; head[x] = tot++; } void dfs(int u) { vis[u] = 1; cnt1++; for (int i = head[u]; i; i = nextt[i]) { int t = i, t2; if (t % 2 == 0) t2 = i - 1; else t2 = i + 1; if (!vis2[i]) { cnt2++; vis2[t] = vis2[t2] = 1; } int v = to[i]; if (!vis[v]) dfs(v); } } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } for (int i = 1; i <= n; i++) { if (!vis[i]) { cnt1 = 0; cnt2 = 0; dfs(i); if (cnt1 == cnt2) { if (ans == 0) ans = 2; else ans = (ans * 2) % mod; } if (cnt1 == cnt2 + 1) { if (ans == 0) ans = cnt1; else ans = (ans * cnt1) % mod; } } } printf("%lld\n", ans); return 0; }
相关文章推荐
- BSOJ3068 BZOJ2500 noip模拟赛 幸福的道路 树的最长链+单调队列 或 RMQ
- [Contest Hunter #54]CH NOIP 2014 模拟赛day1被虐记
- 20161007 NOIP 模拟赛 T1 解题报告
- [NOIP模拟赛]滑板鞋 (倍增)
- 【NOIP模拟赛】买汽水 (dfs+set)
- JZOJ 2017.12.09【NOIP提高组】模拟赛C组
- 【NOIP模拟赛】【数学真奇妙系列】纸盒子
- noip模拟赛 好元素 哈希表的第一题
- 【NOIP模拟赛】【乱搞AC】【贪心】【模拟】匹配
- 纪中训练 day1 【NOIP普及组】模拟赛D组 解题报告
- JZOJ(中山纪中)2018.01.21【NOIP普及组】模拟赛D组(第一题)
- 纪中训练 day5 【NOIP普及组】模拟赛D组 解题报告
- 【jzoj】2018.1.30NOIP普及组——模拟赛D组
- 2016.10.29【初中部 NOIP提高组 】模拟赛C题解
- JZOJ(中山纪中) 2018.02.01【NOIP普及组】模拟赛D组 第三题
- 2- noip模拟赛 DAY2
- 2017.07.15【NOIP提高组】模拟赛B组小结
- 【CJOJ P1957】【NOIP2010冲刺十模拟赛】数字积木
- 【noip2010模拟赛】classroom
- 【NOIP 模拟赛】Evensgn 剪树枝 树形dp