题目链接
题意:
有
n
n
个上锁的门,门后面有若干把对应其他门的钥匙,也可能没有,一个门最多只有一把对应的钥匙,你也可以把门轰炸开取得钥匙,问你轰炸的最少期望次数,能打开所有门。
思路:
一个门不用轰炸能被打开当且它所对应的钥匙已经获得,那么所有门向轰炸它之后能打开的门连一条有向边,那么对于第
i
i
扇门的轰炸概率就是所有门能沿有向边到达它的数量,包括自己, 概率之和就是期望。
#include<bits/stdc++.h>
typedef long long ll;
const int maxn = 1e3 + 5;
using namespace std;
int n, m, T, kase = 1;
bitset<maxn> dis[maxn];
void floyd() {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(dis[j][i]) dis[j] |= dis[i];
}
}
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < maxn; i++) dis[i].reset();
for(int i = 1; i <= n; i++) {
int t; scanf("%d", &t);
dis[i][i] = 1;
while(t--) {
int x; scanf("%d", &x);
dis[i][x] = 1;
}
}
floyd();
double ans = 0;
for(int i = 1; i <= n; i++) {
int cnt = 0;
for(int j = 0; j < maxn; j++) if(dis[j][i]) cnt++;
ans += 1.0 / cnt;
}
printf("Case #%d: %.5f\n", kase++, ans);
}
return 0;
}