ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

A:“大图书馆是一张n点m边的无向图,Marisa和Patchouli初始分别位于点X和点Y。每分钟,两人都有一次行动机会:当某人位于点i时,有pi的概率停留在点i,有1-pi的概率等概率随机选择点i的相邻节点之一并前往。若两人在某个点相遇,则行动停止。值得注意的是,两人在边上是不会相遇的,所以两人在某条边上迎面经过,只会错过而不会相遇。两人同时行动,求两人在每个点相遇的概率。”
B:“这不是CodeForces 113 D吗,还原度真高啊喂。”
A:“那改一改……不求在每个点相遇的概率,改成求两人在相遇前走过的路径长度期望和。”
B:“大同小异。”
A:“大图书馆的m条边的长度是可以修改的,两人的初始位置也是。”
B:“你不要让Patchouli太累了……”

Input

第一行三个正整数n、m、t,表示点数、边数和数据组数
以下m行,每行2个整数a,b,表示点a和点b之间有一条无向边
接下来一行n个实数表示pi,保证0.01<=pi<=0.99
以下t行,每行前m个整数表示每条边的长度,最后2个整数表示初始位置点X和点Y

Output

共t行,每行一个实数表示两人在相遇前走过的路径长度期望和(保留2位小数)
对每个(a,b),将两人起点分别在(a,b)时的答案设为变量,边长看做常量,高斯消元可以把每个变量用常量的线性组合表示出来,于是可以O(m)回答一个询问。
#include<bits/stdc++.h>
int _(){
    int x=0,c=getchar();
    while(c<48)c=getchar();
    while(c>47)x=x*10+c-48,c=getchar();
    return x;
}
int n,m,t,ev[555],id[25][25],idp=0;
double p[25],A[333][633];
struct edge{
    int to,id;
};
std::vector<edge>es[25];
int main(){
    n=_();m=_();t=_();
    for(int i=1;i<=n;++i)for(int j=1;j<i;++j)id[i][j]=id[j][i]=++idp;
    for(int i=1;i<=m;++i){
        int a=_(),b=_();
        es[a].push_back((edge){b,idp+i});
        es[b].push_back((edge){a,idp+i});
    }
    for(int i=1;i<=n;++i)scanf("%lf",p+i);
    for(int w=1;w<=n;++w)for(int u=1;u<w;++u){
        double*f=A[id[w][u]],p1,p2;
        for(int i=0;i<es[w].size();++i){
            p1=(1-p[w])*p[u]/es[w].size();
            p2=(1-p[w])*(1-p[u])/(es[w].size()*es[u].size());
            edge e1=es[w][i];
            f[id[e1.to][u]]+=p1;
            f[e1.id]+=p1;
            for(int j=0;j<es[u].size();++j){
                edge e2=es[u][j];
                f[id[e1.to][e2.to]]+=p2;
                f[e1.id]+=p2;
                f[e2.id]+=p2;
            }
        }
        for(int j=0;j<es[u].size();++j){
            double p1=(1-p[u])*p[w]/es[u].size();
            edge e2=es[u][j];
            f[id[w][e2.to]]+=p1;
            f[e2.id]+=p1;
        }
        f[id[w][u]]+=p[w]*p[u]-1;
    }
    for(int i=1;i<=idp;++i){
        int w=i;
        for(int j=i+1;j<=idp;++j)if(fabs(A[j][i])>fabs(A[w][i]))w=j;
        if(w!=i)for(int k=1;k<=idp+m;++k)std::swap(A[i][k],A[w][k]);
        double v=A[i][i];
        for(int k=i;k<=idp+m;++k)A[i][k]/=v;
        for(int j=1;j<=idp;++j)if(j!=i&&fabs(v=A[j][i])>1e-11)
            for(int k=i;k<=idp+m;++k)A[j][k]-=A[i][k]*v;
    }
    for(;t;--t){
        for(int i=1;i<=m;++i)ev[i]=_();
        int x=_(),y=_();
        if(x==y)puts("0.00");
        else{
            double*f=A[id[x][y]]+idp,s=0;
            for(int i=1;i<=m;++i)s+=f[i]*ev[i];
            printf("%.2f\n",fabs(s));
        }
    }
    return 0;
}

 

posted on 2017-09-13 09:41  nul  阅读(243)  评论(0编辑  收藏  举报