具體鏈接不發了,因爲涉及版權問題
Description
隨着新版百度空間的下線,Blog寵物綠豆蛙完成了它的使命,去尋找它新的歸宿。
給出一個有向無環的連通圖,起點爲1終點爲N,每條邊都有一個長度。綠豆蛙從起點出發,走向終點。
到達每一個頂點時,如果有K條離開該點的道路,綠豆蛙可以選擇任意一條道路離開該點,並且走向每條路的概率爲 1/K 。
現在綠豆蛙想知道,從起點走到終點的所經過的路徑總長度期望是多少?
Input
第一行: 兩個整數 N M,代表圖中有N個點、M條邊
第二行到第 1+M 行: 每行3個整數 a b c,代表從a到b有一條長度爲c的有向邊
Output
從起點到終點路徑總長度的期望值,四捨五入保留兩位小數。
Sample Input
4 4
1 2 1
1 3 2
2 3 3
3 4 4
Sample Output
7.00
Hint
對於100%的數據 N<=100000,M<=2*N
我們可以來看一個例圖
從1到4一共有四種走法,並且期望分別爲
1、2、3、4 1/3 * 1/2 * 1 * ( 1 + 4 + 3)
1、2、4 1/3 * 1/2 * (1 + 4)
1、4 1/3 * 5
1、3、4 1/3 * 1 + (2 + 3)
我們枚舉路徑 , 再挨個算期望 肯定會T掉,所以我們來觀察一下,路徑
1、2、3、4
1、2、4
這兩條,其實他們起點我們都可以看做是2,而且1~2這個我們是可以不管的,那麼這兩個的期望就可以合併到一起來求
我們就可以得到
f[4] = 0
f[3] = (f[4] + 3) / 1
f[2] = (f[3] + 4) / 2 + (f[4] + 4) / 2
f[1] = (f[2] +1) / 3 + (f[3] + 2) / 3 + (f[4] + 5) / 3
那我們就可以根據記憶化來求了 dfs一下就可以了
另外這個題,還可以根據期望的線性性質來計算,也就是計算每個邊的貢獻,這裏就不寫了,下一道題來詳細寫一下
vector<pair<int,double> >v[maxn];
double f[maxn];
double dfs(int x){
if(f[x] > -1.0) return f[x];
f[x] = 0;
for(auto d:v[x]){
int to = d.fi,val = d.se;
f[x] += (dfs(to) + val);
}
f[x] /= v[x].size();
return f[x];
}
int main()
{
int m;
while(cin >> n >> m){
for(int i = 1;i <= m;i++){
int x,y;
double z;cin >> x >> y >> z;
v[x].pb(P(y,z));
}MS1(f); f[n] = 0;
dfs(1);
// cout << f[1] << endl;
wt(f[1],2);
}
return 0;
}