3385. 【NOIP2013模拟】黑魔法师之门 (Standard IO)
Time Limits: 1000 ms Memory Limits: 131072 KB Detailed Limits
Goto ProblemSet做法:咋一看什么头绪都没有,然后。。
实际上每次操作后的答案就是 2^(图中”元”环的个数) -1。 元环的意思如右图所示,(1-2-3-4-1)和(3-4-5-3)是元环, 1-2-3-5-4-1 不是,因为它可以看做由上述的两个环合成。 因为一个环里每个点的度数都是大于零的偶数,我们可以这 样来构造答案:每个环有选和不选两种选择,如果选择了该 环,那么环上所有边的“选择次数”+1。最后取所有“选择次数”为奇数的边构成一个边集, 就是一个答案。可以证明这样构造出来的解不重复且涵盖了所有情况。因此答案就是 2^(图 中”元”环的个数)。实现方法非常简单,只需要一个并查集即可。 具体实现方法: 并查集维护连通性,初始化 ans=1。 加入一条边(x,y)时,如果 x 和 y 在同一集合内,ans*=2。 每次询问输出 ans-1。 时间复杂度 O(Mα(N)),α(N)代表并查集的复杂度。
代码如下:
#include <cstdio> #include <cstring> #include <iostream> #include <string> #define N 400007 using namespace std; int n, m, f[N]; long long ans; int find(int x) { if (f[x] == 0) return x; f[x] = find(f[x]); return f[x]; } int main() { scanf("%d%d", &n, &m); int q, p; ans = 1; for (int i = 1; i <= m; i++) { scanf("%d%d", &q, &p); if (find(q) != find(p)) { f[find(q)] = find(p); } else ans *= 2; ans %= 1000000009; printf("%lld\n", ans - 1); } }