3 3 1 2 1 3 0 0 100 0 0 100 3 1 2 2 3 0 0 100 0 0 100 6 1 2 2 3 1 4 4 5 4 6 0 0 20 30 40 30 50 50 70 10 20 60
Case 1: 2.000000 Case 2: impossible Case 3: 2.895522
对于在点i下一步有3种情况:
1:被杀死回到点1 --- 概率为ki
2:找到出口退出----慨率为ei
3:沿着边进入下一个点
求从点1开始到退出的平均需要走的边数
/*分析: 对于点i: 1,点i是叶子结点,则: E(i)=ki*E(1)+ei*0+(1-ki-ei)*(E(father)+1) =>E(i)=ki*E(1)+(1-ki-ei)*E(father)+(1-ki-ei) 2,点i非叶子结点,则: E(i)=ki*E(1)+ei*0+(1-ki-ei)/m *(E(father)+1)+(1-ki-ei)/m*SUM(E(child)+1) =>E(i)=ki*E(1)+(1-ki-ei)/m *E(father)+(1-ki-ei)/m*SUM(E(child))+(1-ki-ei);//作为1式 从公式可知求E(i)需要求到E(father),E(child) 但这是很难求到的,因为即使是叶子结点也需要知道E(1),但是E(1)是未知的需要求的 假设:E(i)=Ai*E(1)+Bi*E(father)+Ci;//作为2式 所以:E(child)=Aj*E(1)+Bj*E(i)+Cj; =>SUM(E(child))=SUm(Aj*E(1)+Bj*E(i)+Cj); 带入1式 =>E(i)=ki*E(1)+(1-ki-ei)/m *E(father)+(1-ki-ei)/m*SUm(Aj*E(1)+Bj*E(i)+Cj)+(1-ki-ei); =>(1-(1-ki-ei)/m*SUM(Bj))*E(i)=(ki+(1-ki-ei)/m*SUM(Aj))*E(1)+(1-ki-ei)/m *E(father)+(1-ki-ei+(1-ki-ei)/m*SUM(cj)); 与上述2式对比得到: Ai=(ki+(1-ki-ei)/m*SUM(Aj)) / (1-(1-ki-ei)/m*SUM(Bj)) Bi=(1-ki-ei)/m / (1-(1-ki-ei)/m*SUM(Bj)) Ci=(1-ki-ei+(1-ki-ei)/m*SUM(cj)) / (1-(1-ki-ei)/m*SUM(Bj)) 所以Ai,Bi,Ci只与i的孩子Aj,Bj,Cj和本身ki,ei有关 于是可以从叶子开始逆推得到A1,B1,C1 在叶子节点: Ai=ki; Bi=(1-ki-ei); Ci=(1-ki-ei); 而E(1)=A1*E(1)+B1*0+C1; =>E(1)=C1/(1-A1); */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <map> #include <cmath> #include <iomanip> #define INF 99999999 typedef long long LL; using namespace std; const int MAX=10000+10; const double eps=1e-9; int n,size; int head[MAX]; double A,B,C,k[MAX],e[MAX]; struct Edge{ int v,next; Edge(){} Edge(int V,int NEXT):v(V),next(NEXT){} }edge[MAX*2]; void Init(){ memset(head,-1,sizeof head); size=0; } void InsertEdge(int u,int v){ edge[size]=Edge(v,head[u]); head[u]=size++; } void dfs(int u,int father){ double a=0,b=0,c=0,p; int m=0; for(int i=head[u]; i != -1;i=edge[i].next){ int v=edge[i].v; if(v == father)continue; dfs(v,u); a+=A; b+=B; c+=C; ++m; } if(father != -1)++m; p=(1-k[u]-e[u])/m; A=(k[u]+p*a)/(1-p*b); B=p/(1-p*b); C=(1-k[u]-e[u]+p*c)/(1-p*b); } int main(){ int t,u,v,num=0; scanf("%d",&t); while(t--){ scanf( "%d",&n); Init(); for(int i=1;i<n;++i){ scanf("%d%d",&u,&v); InsertEdge(u,v); InsertEdge(v,u); } for(int i=1;i<=n;++i){ scanf("%lf%lf",&k[i],&e[i]); k[i]/=100; e[i]/=100; } dfs(1,-1); if(fabs(A-1)<eps)printf("Case %d: impossible\n",++num); else printf("Case %d: %.6f\n",++num,C/(1-A)); } return 0; }