HDU 5036 Explosion
2018-10-09 20:12
316 查看
Explosion
http://acm.hdu.edu.cn/showproblem.php?pid=5036
题意:
n扇门,每扇门里面有一些钥匙,一个钥匙可以打开一扇门,如果没有钥匙可以打开门,那么随机选择一扇门炸开。求期望炸多少次。
分析:
bitset优化Floyd传递闭包。
根据期望的线性性,求出每扇门炸的概率,乘以1就是答案。将原问题转化为一张有向图,x->y,说明x有y的钥匙。如果有s扇门可以到达x(不一定连向,联通即可,说明到了这个点,然后根据这个点的钥匙,到下一个点,最后直到x),那么炸x的概率就是1/s。x也在这s个里面,表示可以直接炸x。然后用bitset优化Floyd,求传递闭包。
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream> #include<cctype> #include<set> #include<vector> #include<queue> #include<map> #include<bitset> #define fi(s) freopen(s,"r",stdin); #define fo(s) freopen(s,"w",stdout); using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 1001; bitset<N> e ; void solve() { int n = read(); for (int i=1; i<=n; ++i) e[i].reset(), e[i].set(i); for (int i=1; i<=n; ++i) for (int x = read(), y; x --; ) y = read(), e[i].set(y); for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) if (e[j][i]) e[j] |= e[i]; double sum = 0, cnt = 0; for (int i=1; i<=n; ++i) { cnt = 0; for (int j=1; j<=n; ++j) if (e[j][i]) cnt ++; sum += 1.0 / cnt; } printf("%.5lf\n",sum); } int main() { int T = read(); for (int i=1; i<=T; ++i) { printf("Case #%d: ",i); solve(); } return 0; }
相关文章推荐
- HDU 5036 Explosion 概率 期望
- HDU 5036 Explosion(北京网络赛E题)
- hdu 5036 Explosion(bitset处理概率)
- HDU - 5036 Explosion
- HDU 5036 Explosion
- HDU 5036 Explosion 2014 北京网络赛E题
- hdu 5036 Explosion 2014 ACM/ICPC Asia Regional Beijing Online
- HDU 5036 Explosion 概率 期望
- hdu 5036 Explosion
- Hdu 5036-Explosion 传递闭包,bitset,期望/概率
- HDU - 5036 Explosion
- HDU - 5036 Explosion(期望+bitset)【存疑】
- hdu 5036 Explosion (期望+传递闭包)
- HDU 5036 Explosion (2014年北京赛区网络赛E题)
- hdu_5036_Explosion(bitset优化传递闭包)
- hdu 5036 Explosion(有向图的删点期望+bitset优化)
- hdu 5036 Explosion(概率期望+bitset)
- HDU 5036 explosion
- HDU - 5036 Operation the Sequence
- hdu 5036 概率+bitset