题意
n种药剂,m个反应关系,药剂依次加入缸里(顺序其实并没有关系),若发生反应,danger翻倍,问danger是多少。
看题意的可以点叉叉了
题解
yy一下建个图,n个点,m条边
显然要求的是 总点数-连通块数,因为一个连通块能带来的danger是2^(连通块中点数-1).
用并查集做一下就好了。
不缺并查集模板的可以回去抄模板写了。。。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#include <set>
using namespace std;
const int MAXSIZE = 100020;
int uset[MAXSIZE];
void makeSet(int size) {
for(int i = 0;i < size;i++) uset[i] = -1;
}
int find(int x) {
if (uset[x] < 0) return x;
uset[x] = find(uset[x]);
return uset[x];
}
void unionSet(int x, int y) {
if ((x = find(x)) == (y = find(y))) return;
if (uset[x] < uset[y]) {
uset[x] += uset[y];
uset[y] = x;
} else {
uset[y] += uset[x];
uset[x] = y;
}
}
long long pow_mod(long long a,long long b,long long m)
{
long long res = 1, base = a;
while(b != 0)
{
if (b & 1)
res = (res*base)%m;
base *= base;
b >>= 1;
}
return res;
}
int main()
{
int m,n;
cin>>m>>n;
if (m==1)
{
cout<<"1"<<endl;
return 0;
}
makeSet(m+1);
int a,b=1;
for (int i=0;i<n;i++)
{
cin>>a>>b;
unionSet(a,b);
}
int ans=0;
for (int i=1;i<=m;i++)
{
if (find(i)==i)
ans++;
}
cout<<pow_mod(2,m-ans,1LL<<61)<<endl;
return 0;
}