洛谷P2973 [USACO10HOL]赶小猪

https://www.luogu.org/problemnew/show/P2973

dp一遍,\(f_i=\sum_{edge(i,j)}\frac{f_j\times(1-\frac{P}{Q})}{du_j} + \frac{P}{Q}\)

然后发现有环,高斯消元一遍

(zz到高斯消元都能写错。。。)

#include<bits/stdc++.h>
#define il inline
#define vd void
#define double long double
typedef long long ll;
il int gi(){
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int fir[301],dis[90010],nxt[90010],id,in[301];
il vd link(int a,int b){nxt[++id]=fir[a],fir[a]=id,dis[id]=b;}
#define eps 1e-13
double s[301][302];
int main(){
    int n=gi(),m=gi(),p=gi(),q=gi(),a,b;
    while(m--)a=gi(),b=gi(),link(a,b),link(b,a),++in[a],++in[b];
    for(int i=1;i<=n;++i){
        if(i==1)s[i][n+1]=1;
        for(int j=fir[i];j;j=nxt[j])
            s[i][dis[j]]=(p*1.0/q-1)/(in[dis[j]]);
        s[i][i]=1;
    }
    for(int i=1;i<=n;++i){
        int t=i;  
        for(int j=i;j<=n;++j)if(fabs(s[j][i])>eps){t=j;}
        for(int j=1;j<=n+1;++j)std::swap(s[t][j],s[i][j]);
        for(int j=i+1;j<=n;++j){
            if(fabs(s[j][i])<eps)continue;
            for(int k=n+1;k>=i;--k)s[j][k]-=s[i][k]*s[j][i]/s[i][i];
        }
    }
    for(int i=n;i;--i){
        for(int j=i+1;j<=n;++j)s[i][n+1]-=s[j][n+1]*s[i][j];
        s[i][n+1]/=s[i][i];
    }
    for(int i=1;i<=n;++i)printf("%.9Lf\n",s[i][n+1]*p/q);
    return 0;
}
posted @ 2018-10-03 14:30  菜狗xzz  阅读(266)  评论(0编辑  收藏  举报