Luogu P4316 綠豆蛙的歸宿
阿新 • • 發佈:2018-06-30
隨著 queue 整數 spa 歸宿 blog stream IT 輸入輸出
P4316 綠豆蛙的歸宿
題意翻譯
「Poetize3」
題目背景
隨著新版百度空間的上線,Blog寵物綠豆蛙完成了它的使命,去尋找它新的歸宿。
題目描述
給出一個有向無環圖,起點為1終點為N,每條邊都有一個長度,並且從起點出發能夠到達所有的點,所有的點也都能夠到達終點。綠豆蛙從起點出發,走向終點。 到達每一個頂點時,如果有K條離開該點的道路,綠豆蛙可以選擇任意一條道路離開該點,並且走向每條路的概率為 1/K 。 現在綠豆蛙想知道,從起點走到終點的所經過的路徑總長度期望是多少?
輸入輸出格式
輸入格式:
第一行: 兩個整數 N M,代表圖中有N個點、M條邊 第二行到第 1+M 行: 每行3個整數 a b c,代表從a到b有一條長度為c的有向邊
輸出格式:
從起點到終點路徑總長度的期望值,四舍五入保留兩位小數。
輸入輸出樣例
輸入樣例#1:4 4 1 2 1 1 3 2 2 3 3 3 4 4
輸出樣例#1:
7.00
說明
對於20%的數據 N<=100
對於40%的數據 N<=1000
對於60%的數據 N<=10000
對於100%的數據 N<=100000,M<=2*N
根據題意,總的期望路徑長度$=\sum$每條邊經過的概率*每條邊的權值
又因為是有向無環圖,所以每條邊經過的概率等於經過這條邊的終點的概率
這樣的話我們就可以在拓撲排序的過程中進行計算
代碼
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> const int maxn = 1e5+3; using namespace std; queue<int> Node; double f[maxn], ans, dis[maxn]; int n, m, indgr[maxn], cnt = 1, oudgr[maxn]; int first[maxn*2], next[maxn*2], u[maxn*2], v[maxn*2], w[maxn*2]; inline int read() { int x = 0, f = 1; char c = getchar(); while (c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while (c <= ‘9‘ && c >= ‘0‘) { x = x*10+c-‘0‘; c = getchar(); } return x * f; } int main() { n = read(), m = read(); memset(first, -1, sizeof(first)); for(int i=1; i<=m; i++) { u[i] = read(), v[i] = read(), w[i] = read(); indgr[v[i]] ++; oudgr[u[i]] ++; next[i] = first[u[i]]; first[u[i]] = i; } for(int i=1; i<=n; i++) if(!indgr[i]) { Node.push(i); f[i] = 1.0; } while (cnt < n) { int x = Node.front(); Node.pop(); int k = first[x]; while (k != -1) { indgr[v[k]]--; double s = (double(f[u[k]])/double(oudgr[u[k]])); f[v[k]] += (double(f[u[k]])/double(oudgr[u[k]])); ans += s * w[k]; if(indgr[v[k]] == 0) { Node.push(v[k]); cnt++; } k = next[k]; } } printf("%.2lf", ans); return 0; }
Luogu P4316 綠豆蛙的歸宿