Luogu P4316 绿豆蛙的归宿 题解报告
【题目大意】
给一张有n个点,m条边的有向图,对于每一个点,走向其每一条出边的概率是相同的,求从起点1到终点n的期望路径长度。
【思路分析】
这题很简单,如果设f[x]为从点x到终点的期望路径长度,x有k条出边,分别连接y1,y2,…,yk,长度分别为d1,d2,…,dk,那么有$f[x]=\frac{1}{k}\sum_{i=1}^{k}(f[y_i]+d_i)$
边界条件为f[n]=0
书上说还要拓扑排序什么的,我直接用递归也能AC(不知道484因为数据够水)
【代码实现】
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define go(i,a,b) for(register int i=a;i<=b;i++) 4 using namespace std; 5 const int N=100002; 6 int head[N],next[N<<1],to[N<<1],len[N<<1],du[N]; 7 int fr(){ 8 int w=0,q=1; 9 char ch=getchar(); 10 while(ch<'0'||ch>'9'){ 11 if(ch=='-') q=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9') 15 w=(w<<1)+(w<<3)+ch-'0',ch=getchar(); 16 return w*q; 17 } 18 int n,m,num=0; 19 double f[N]; 20 double F(int x){ 21 if(x==n) return 0; 22 if(f[x]) return f[x]; 23 for(register int i=head[x];i;i=next[i]){ 24 int t=to[i]; 25 f[x]+=F(t)+len[i]; 26 } 27 f[x]=(double)f[x]/du[x]; 28 return f[x]; 29 } 30 int main(){ 31 memset(f,0,sizeof(f)); 32 n=fr();m=fr(); 33 go(i,1,m){ 34 int a=fr(),b=fr(),c=fr(); 35 next[++num]=head[a];to[num]=b;len[num]=c;head[a]=num;du[a]++; 36 } 37 f[N]=0; 38 f[1]=F(1); 39 printf("%.2lf\n",f[1]); 40 return 0; 41 }