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