题目链接:hdu_5036_Explosion
题意:
一个人要打开或者用炸弹砸开所有的门,每个门里面有一些钥匙,一个钥匙对应一个门,有了一个门的钥匙就能打开相应的门,告诉每个门里面有哪些门的钥匙,问需要用的炸弹为多少。
思路:
考虑每个点需要用炸弹打开的概率,那么所有点的概率之和就是解。首先用bitset优化一个floyd,将每个门可以由那些门打开,就是有多少种方案,对于这个门的期望就是1/cnt,然后相加就行。
PS:这里运用了bitset优化到了n^3/64.
#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int N=;
int t,ic=,n;
bitset<N>mp[N]; int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
F(i,,n)mp[i].reset(),mp[i][i]=;
F(i,,n)
{
int m,tp;
scanf("%d",&m);
F(j,,m)scanf("%d",&tp),mp[i][tp]=;
}
F(i,,n)F(j,,n)if(mp[j][i])mp[j]|=mp[i];
double ans=;
F(i,,n)
{
int cnt=;
F(j,,n)if(mp[j][i])cnt++;
ans+=1.0/cnt;
}
printf("Case #%d: %.5f\n",ic++,ans);
}
return ;
}