2019 icpc 南京网络赛 D题 Robots 随机游走模板题

/*
 *题意:给出一个有向无环图,有个机器人开始时在源点S,每次停留在原地或走向相邻点的概率相同,每一天机器人消耗1能量,问机器人到达汇点的消耗能量的期望
 *题解:随机游走问题
 *  dp[u] = dp[u] / (outdeg[u] + 1) + dp[v] / (outdeg[u] + 1) + 1
 */
#include <bits/stdc++.h>
#define FOR(i,s,t) for(int i=(s);i<=(t);i++)
#define ROF(i,s,t) for(int i=(s);i>=(t);i--)
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 1e6 + 6;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int readInt(){
    int x=0;
    bool sign=false;
    char c=getchar();
    while(!isdigit(c)){
        sign=c=='-';
        c=getchar();
    }
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return sign?-x:x;
}
ll readLong(){
    ll x=0;
    bool sign=false;
    char c=getchar();
    while(!isdigit(c)){
        sign=c=='-';
        c=getchar();
    }
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return sign?-x:x;
}
string readString(){
    string s;
    char c=getchar();
    while(isspace(c)){
        c=getchar();
    }
    while(!isspace(c)){
        s+=c;
        c=getchar();
    }
    return s;
}
int i,i0,n,m,T,ans,in[100005];
vector<int>edge[100005];
const int mx=60;
long double dp[100005][mx+5][2];
queue<int>q;
int main()
{
    T = readInt();
    while(T--){
        n =readInt();
        m =readInt();
        FOR(i,1,n){
			edge[i].clear(),in[i]=0;
			FOR(i0,1,mx)dp[i][i0][0]=dp[i][i0][1]=0;
		}
        while(m--){
            int u = readInt() ,v = readInt();
            edge[u].push_back(v);
            in[v]++;
        }
		dp[1][1][0]=1;
		long double ans=0;
        q.push(1);
        while(q.size()){
            int t=q.front();
            q.pop();
			if(edge[t].size()){
				FOR(i,2,mx){
					dp[t][i][0]=(dp[t][i-1][0])/(edge[t].size()+1);
					dp[t][i][1]=(dp[t][i-1][1]+dp[t][i-1][0])/(edge[t].size()+1);
					ans+=dp[t][i][1];
				}
			}
            for(auto x:edge[t]){
				FOR(i,1,mx){
					dp[x][1][0]+=(dp[t][i][0])/(edge[t].size()+1);
					dp[x][1][1]+=(dp[t][i][1]+dp[t][i][0])/(edge[t].size()+1);
					ans+=(dp[t][i][1]+dp[t][i][0])/(edge[t].size()+1);
				}
                in[x]--;
                if(!in[x])q.push(x);
            }
        }
        printf("%.2Lf\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值