列表

详情


NC210515. 迷宫游戏

描述

吉吉国王小时候非常喜欢走迷宫,因此在他掌控了国家之后就立马修建了许多有趣的迷宫,其中有一款迷宫游戏是这样的。这个迷宫可以看成有个房间并且有条双向边连接的联通图,吉吉国王一开始站在号节点时,吉吉国王在每个房间有三种事件。
第一种事件:吉吉国王有的概率触发了传送门被传送到了号房间。
第二种事件:吉吉国王所在房间有的概率随机产生了出口,吉吉国王通过了迷宫游戏。
第三种事件:吉吉国王等概率的选择一条这个房间连接的边,并且走向下一个房间。
现在吉吉国王想知道他在完成迷宫游戏时走过的边的数量的期望值。

输入描述

第一行一个整数表示房间的数量。
接下来行每行两个整数表示编号为和编号为的房间有一条双向边连接。
最后行每行两个整数表示在第个房间传送到号房间的概率的百分比和在第个房间遇到出口的概率的百分比。

输出描述

输出一个小数表示吉吉国王走出迷宫时走过的边的期望值。如果用表示你输出的答案,表示标准答案,如果就认为答案正确
无解时输出“impossible”

示例1

输入:

3
2 3
1 2
0 0
30 32
59 28

输出:

3.6977491961

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 59ms, 内存消耗: 48120K, 提交时间: 2022-11-01 21:44:23

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2000010;
vector<int> g[N];
double e[N],k[N];
double A[N],b[N],B[N];
int flag=1;
double eps=1e-9;
void dfs(int x,int fa)
{
    A[x]=k[x];
    b[x]=B[x]=1.0-k[x]-B[x];
    double suma=0,sumb=0,sumc=0;
    int son=0;
    
    for(auto to:g[x])
    {
        if(to==fa) continue;
        dfs(to,x);
        suma+=A[to];
        sumb+=b[to];
        sumc+=B[to];
        son++;
    }
 
        double p=(1-k[x]-e[x])/(g[x].size());
        if(fabs(1-p*sumb)<eps)
        {
            flag=0;
            return ;
        }
        A[x]=(k[x]+p*suma)/(1-p*sumb);
        b[x]=p/(1-p*sumb);
        B[x]=(p*sumc+p*g[x].size())/(1-p*sumb);
    
}
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        k[i]=x*1.0/100;
        e[i]=y*1.0/100;
    }
    dfs(1,0);
    printf("%.10lf",B[1]/(1-A[1]));
}

C++(clang++ 11.0.1) 解法, 执行用时: 7ms, 内存消耗: 1280K, 提交时间: 2022-12-07 20:48:09

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0;char c=getchar();
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
    return x;
}
vector<int>f[10010];
int n,a[10004],b[10004];
double A[10004],B[10004],C[10004];
void dfs(int x,int fa){
	A[x]=1.0*b[x]/100;
	B[x]=1.0*a[x]/100;
	int siz=f[x].size();
	C[x]=1.0*a[x]/100/siz;
	double k=1;
	for(int y:f[x]){
		if(y==fa)continue;
		dfs(y,x);
		A[x]+=A[y]*a[x]/100/siz;
		B[x]+=B[y]*a[x]/100/siz;
		k-=C[y]*a[x]/100/siz;
	}
	A[x]/=k;
	B[x]/=k;
	C[x]/=k;
	return;
}
int main(){
    n=read();
    for(int i=1;i<n;i++){
    	int u=read(),v=read();
    	f[u].push_back(v);
    	f[v].push_back(u);
	}
	for(int i=1;i<=n;i++){
		b[i]=read();
		a[i]=100-b[i]-read();
	}
	dfs(1,0);
	printf("%.13lf",B[1]/(1.0-A[1]));
	return 0;
}

上一题