HDU 5036 Explosion 【bitset】

HDU5036链接

题意:有n个房间,每个房间都有k(0<=k<=n)把钥匙,你可以用炸弹炸开一扇门,获得房间里的钥匙。最初,你没有钥匙,当你手中没有钥匙时,你会随机炸一扇门,如果手中有钥匙,你会打开那扇门,获得其中钥匙,问当你打开所有的门,你使用炸弹的期望值。

分析:求打开所有门的总期望,可以先求每一扇门的期望,然后加起来。对于一扇门x,使用炸弹的期望只和这扇门的前导门有关(前导门为炸了前导门后,能够不使用钥匙就能打开x门)。设x的前导门数量为S。则门x的期望为1/(s+1)。这个可以用bitset处理。看到网上有用强连通分量处理,然后再用bitset。其实强连通分量处理一步并不能简化bitset运算。用强连通并无意义。

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
bitset<N>k[N];
int main()
{
    int cas=1,TA,n,x,y;
    scanf("%d",&TA);
    while(TA--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)k[i].reset(),k[i][i]=true;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&x);
            while(x--)
            {
                scanf("%d",&y);
                k[i][y-1]=true;
            }
        }
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                if(k[j][i])
                    k[j]|=k[i];
        double ans = 0.0;
        for(int j=0; j<n; ++j)
        {
            int cnt=0;
            for(int i=0; i<n; ++i)
                if(k[i][j]) cnt++;
            ans += 1.0 / cnt;
        }

        printf("Case #%d: %.5f\n",cas++,ans);
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37953323/article/details/80200108