黑魔法师之门【并查集】
题目大意:
有一张无向无权图,求每一时刻图中每个点的度数大于零且都是偶数的子图的个数对1000000009取模的值。此处子图 (V, E) 定义为:点集V和边集E都是原图的任意子集,其中E中的边的端点都在V中。
思路:
由于每一时刻都要输出,所以DFS肯定是不行的,像 连通块 一样,正解是并查集。
题目中图中每个点的度数大于零且都是偶数的子图的个数这句话十分重要。它告诉我们,其实是要输出图中环的个数!
那么我们可以发现,每当读入一条边时,若这两个点本来就是连通的,那么在加上这条线就成了环,而交换的环则是以前交换的环的数量。所以,我们只要记录一个环的数量,就能轻轻松松的求出答案。
代码:
#include <cstdio>
#include <iostream>
using namespace std;
long long father[200001],n,m,x,y,ans;
int find(int x) //并查集不解释
{
return x==father[x]?x:father[x]=find(father[x]);
}
int main()
{
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;i++)
father[i]=i; //初始化
for (int i=1;i<=m;i++)
{
scanf("%lld%lld",&x,&y);
if (find(x)==find(y)) ans=ans*2+1; //增加了环
else father[find(y)]=find(x); //连边
ans%=1000000009;
printf("%lld\n",ans);
}
return 0;
}