先贴题面w
1065. [Nescafe19] 绿豆蛙的归宿
★ 输入文件:
ldfrog.in
输出文件:ldfrog.out
简单对比
时间限制:1 s 内存限制:128 MB随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿。
Description
给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度。绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。
现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少?Input
第一行: 两个整数 N M,代表图中有N个点、M条边
第二行到第 1+M 行: 每行3个整数 a b c,代表从a到b有一条长度为c的有向边Output
从起点到终点路径总长度的期望值,四舍五入保留两位小数。
Sample Input
1 2 1 1 3 2 2 3 3 3 4 4Sample Output
4 47.00
Time Limit
各个测试点1s
HINT
对于20%的数据 N<=100
对于40%的数据 N<=1000
对于60%的数据 N<=10000
对于100%的数据 N<=100000,M<=2*N
我们可以设$f_{i}$为从结点$i$到结点$v$的期望距离
由于题目保证数据是$DAG$所以我们可以按照拓扑序的逆序来递推而不用$Gaussian Elimination$解方程组
先删结点$v$的出边,然后DFS一遍把拓扑序扔到队列里
然后按顺序推,公式如下:[f_i=sum_{(i,j)in E}frac{f_j+dis}{outDegree}]
其中$dis$为$(i,j)$边的长度,$outDegree$为结点$i$的出度
(其实完全不用保存拓扑序直接DFS一遍然后在回溯的时候推就可以的QAQ可能因为我比较蒟蒻吧)
好了不扯了...参考代码吧OwO
1 /********************************* 2 Judge Result:Accepted 3 4 *********************************/ 5 #include <queue> 6 #include <cstdio> 7 #include <cstring> 8 #include <cstdlib> 9 #include <iostream> 10 #include <algorithm> 11 12 const int MAXE=200010; 13 const int MAXV=100010; 14 15 struct Edge{ 16 int from; 17 int to; 18 int dis; 19 Edge* next; 20 }; 21 22 Edge E[MAXE]; 23 Edge* head[MAXV]; 24 Edge* top=E; 25 26 int v; 27 int e; 28 int otd[MAXV]; 29 int ind[MAXV]; 30 double dp[MAXV]; 31 bool visited[MAXV]; 32 std::queue<int> tpo; 33 34 void Insert(int,int,int); 35 void Initialize(); 36 void DFS(int root); 37 38 int main(){ 39 Initialize(); 40 head[v]=NULL; 41 dp[v]=0; 42 DFS(1); 43 while(!tpo.empty()){ 44 int top=tpo.front(); 45 tpo.pop(); 46 for(Edge* i=head[top];i!=0;i=i->next){ 47 dp[top]+=(double(i->dis)+dp[i->to])/double(otd[top]); 48 } 49 } 50 printf("%.2lf ",dp[1]); 51 return 0; 52 } 53 54 void DFS(int root){ 55 visited[root]=true; 56 for(Edge* i=head[root];i!=NULL;i=i->next){ 57 if(!visited[i->to]) 58 DFS(i->to); 59 } 60 tpo.push(root); 61 } 62 63 void Initialize(){ 64 #ifndef ASC_LOCAL 65 freopen("ldfrog.in","r",stdin); 66 freopen("ldfrog.out","w",stdout); 67 #endif 68 int from,to,dis; 69 scanf("%d%d",&v,&e); 70 for(int i=0;i<e;i++){ 71 scanf("%d%d%d",&from,&to,&dis); 72 Insert(from,to,dis); 73 } 74 } 75 76 inline void Insert(int from,int to,int dis){ 77 top->to=to; 78 top->dis=dis; 79 top->from=from; 80 top->next=head[from]; 81 head[from]=top; 82 otd[from]++; 83 ind[to]++; 84 top++; 85 }
图包作为结束w