Robots
Given a directed graph with no loops which starts at node 11 and ends at node nn.
There is a robot who starts at 11, and will go to one of adjacent nodes or stand still with equal probability every day.
Every day the robot will have durability consumption which equals to the number of passed days.
Please calculate the expected durability consumption when the robot arrives at node nn.
It is guaranteed that there is only one node (node 1) whose in-degree is equal to 0,
and there is only one node (node n) whose out-degree is equal to 0. And there are no multiple edges in the graph.
Input
The first line contains one integer T (1≤T≤10)
For each case,the first line contains two integers n (2≤n≤10^5) and m (1≤m≤2×10^5), the number of nodes and the number of edges, respectively.
Each of the next mm lines contains two integers u and v (1≤u,v≤n) denoting a directed edge from u to v.
It is guarenteed that ∑n≤4×10^5, and ∑m≤5×10^5.
Output
Output T lines.Each line have a number denoting the expected durability consumption when the robot arrives at node n.
Please keep two decimal places.
样例输入
1
5 6
1 2
2 5
1 5
1 3
3 4
4 5
样例输出
9.78
翻译:
给定一个没有循环的有向图,它从节点11开始,在节点nn结束。
有一个机器人从11岁开始,每天都以相同的概率走到相邻的一个节点,或者站着不动。
机器人每天的耐用性消耗相当于过去的天数。
请计算机器人到达节点nn时的预期耐久性消耗。
保证只有一个节点(节点1)的入度为0,
并且只有一个节点(节点n)的出度等于0。图中没有多条边
输入
第一行包含一个整数T(1≤T≤10)
对于每种情况,第一行包含两个整数n(2≤n≤10^5)和m(1≤m≤2×10^5),分别为节点数和边数。
接下来的mm线每条都包含两个整数u和v(1≤u,v≤n),表示从u到v的有向边。
∑n≤4×10^5,∑m≤5×10^5。
输出
输出线。每一行都有一个数字,表示机器人到达节点n时的预期耐久性消耗。
请保留两位小数。
官方题解:
dp[i] :1到N的天数期望;
f[i]:花费代价期望;
out[i]表示点的出度;
天数期望方程
dp[i] = 1/( out[i] + 1 )*dp[i] + 1/( out[i] + 1 )*∑dp[j] + 1;
移式化简后:
dp[i] = 1/out[i]*∑dp[j] + 1 + 1/out[i];
花费期望:
f[i]=1/( out[i] + 1 )*f[i] + 1/( out[i] + 1)*∑f[j] + dp[i];
移式化间后:
f[i] = 1/out[i]*∑f[j] + (out[i] + 1) / out[i] * dp [ i ];
ac代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 110000;
int t,n,m;
int out[2*N];
double dp[2*N],f[2*N];
vector<int> v[2*N];
void init(){
for(int i=0;i<=n;i++){
v[i].clear();
dp[i] = 0;
f[i] = 0;
out[i] = 0;
}
}
double dfsdp(int x){
if(dp[x]!=0) return dp[x];
if(out[x] == 0) return dp[x];
int len = v[x].size();
double s1=0;
for(int i=0;i<len;i++){
int e=v[x][i];
dfsdp(e);
s1+=dp[e];
}
dp[x]=s1/out[x]*1.0+1+1.0/out[x];
return dp[x];
}
double dfsf(int x){
if(f[x]!=0) return f[x];
if(out[x] == 0) return f[x];
int len = v[x].size();
double s1=0;
for(int i=0;i<len;i++){
int e=v[x][i];
dfsf(e);
s1+=f[e];
}
f[x]=s1/out[x]*1.0+(1+1.0/out[x]*1.0)*dp[x];
return f[x];
}
int main(){
int a,b;
int t;
cin>>t;
while(t--){
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&a,&b);
out[a]++;
v[a].push_back(b);
}
dfsdp(1);
dfsf(1);
printf("%.2f\n",f[1]);
}
return 0;
}
原文地址:https://www.cnblogs.com/lusiqi/p/11491056.html