BZOJ1778: [Usaco2010 Hol]Dotp 驱逐猪猡

给出n个节点m条边无向图,炸弹从1开始走,有p/q的概率爆炸,否则等概率移到别的点
求在每个点爆炸概率
f[i,j]-第j秒到点i的概率 W=p/q 则f[i,j]=sigma(1-W)/D[i]*f[k,j-1]
其中D[i]为点i的度,k与i有连边
Ans(i)=W(f[i,0]+f[i,1]+f[i,2]+……)
=Wf[i,0]+W(1-W)/D[i](sigma f[k,0]+sigma f[k,1]+sigma f[k,2]……)
=Wf[i,0]+sigma (1-W)/D[i]*Ans(k),高斯消元解即可。
以上为典型的错误!!系数写错,把D[i]改成D[k]即可。

第一次写,很顺;第二次,系数配错,高斯消元写错,WA两发。

很好。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<math.h>
 5 //#include<iostream>
 6 using namespace std;
 7 
 8 const double eps=1e-13;
 9 int n,m;
10 #define maxn 311
11 #define maxm 100011
12 struct Edge{int to,next;};
13 struct Graph
14 {
15     Edge edge[maxm];
16     int first[maxn],le,du[maxn];
17     Graph()
18     {
19         memset(first,0,sizeof(first));le=2;
20         memset(du,0,sizeof(du));
21     }
22     void in(int x,int y)
23     {
24         edge[le].to=y;
25         edge[le].next=first[x];
26         first[x]=le++;
27     }
28     void insert(int x,int y)
29     {
30         in(x,y);
31         in(y,x);
32         du[x]++;du[y]++;
33     }
34 }g;
35 double mat[maxn][maxn];
36 int x,y;double w;
37 void gauss()
38 {
39     for (int i=1;i<=n;i++)
40     {
41         int r=i;
42         for (int j=i+1;j<=n;j++) if (mat[j][i]>mat[r][i]) r=j;
43         for (int j=i;j<=n+1;j++) {double t=mat[r][j];mat[r][j]=mat[i][j];mat[i][j]=t;}
44         for (int j=i+1;j<=n;j++)
45             for (int k=n+1;k>=i;k--)
46                 mat[j][k]-=mat[j][i]/mat[i][i]*mat[i][k];
47     }
48     for (int i=n;i>=1;i--)
49     {
50         for (int j=n;j>i;j--) mat[i][n+1]-=mat[j][n+1]*mat[i][j];
51         mat[i][n+1]/=mat[i][i];
52     }
53 }
54 int main()
55 {
56     scanf("%d%d%d%d",&n,&m,&x,&y);
57     if (x>y) x=y;w=(double)x/y;
58     for (int i=1;i<=m;i++)
59     {
60         scanf("%d%d",&x,&y);
61         g.insert(x,y);
62     }
63     for (int i=1;i<=n;i++)
64     {
65         for (int j=1;j<=n+1;j++) mat[i][j]=0.0;
66         for (int j=g.first[i];j;j=g.edge[j].next)
67         {
68             Edge &e=g.edge[j];
69             mat[i][e.to]+=(w-1)/g.du[e.to];
70         }
71         mat[i][i]=1.0;
72     }
73     mat[1][n+1]=w;
74     gauss();
75     for (int i=1;i<=n;i++) printf("%.9f\n",mat[i][n+1]);
76     return 0;
77 }
View Code

 

posted @ 2017-08-28 12:54  Blue233333  阅读(213)  评论(0编辑  收藏  举报