zoukankan      html  css  js  c++  java
  • bzoj1415: [Noi2005]聪聪和可可

    spfa+dp。

    首先用一个类似spfa的过程求出a[s][t],聪聪在s,可可在t时,聪聪第一步怎么走。

    然后dp求出f[s][t],表示聪聪在s,可可在t的期望步数。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 1000 + 10;
    const int maxm = 2000 + 10;
    
    int g[maxn],v[maxm],next[maxm],eid;
    int n,m,s,t,u;
    int q[maxm*10],l,r;
    int deg[maxn],dist[maxn],a[maxn][maxn];
    double f[maxn][maxn];
    bool inque[maxn];
    
    void addedge(int a,int b) {
        v[eid]=b; next[eid]=g[a]; g[a]=eid++;
        v[eid]=a; next[eid]=g[b]; g[b]=eid++;
        deg[a]++; deg[b]++;
    }
    
    void spfa(int s) {
        memset(dist,0x3f,sizeof(dist)); l=r=0;
        dist[s]=0; a[s][s]=s;
        for(int i=g[s];~i;i=next[i]) {
            dist[v[i]]=1;
            a[s][v[i]]=v[i];
            inque[q[r++]=v[i]]=1;        
        }
        
        while(l<r) {
            inque[u=q[l++]]=0;
            for(int i=g[u];~i;i=next[i]) 
                if(dist[v[i]]>dist[u]+1) {
                    dist[v[i]]=dist[u]+1;
                    a[s][v[i]]=a[s][u];
                    if(!inque[v[i]]) 
                        inque[q[r++]=v[i]]=1;
                }
                else if(dist[v[i]]==dist[u]+1 && a[s][u]<a[s][v[i]] ) {
                    a[s][v[i]]=a[s][u];
                    if(!inque[v[i]]) 
                        inque[q[r++]=v[i]]=1;
                }
            }
        //for(int i=1;i<=n;i++) printf("a[%d][%d]=%d
    ",s,i,a[s][i]);    
            
    }
    
    
    double dp(int s,int t) {
        if(f[s][t]>=0) return f[s][t];
        int p=a[a[s][t]][t];
        double sum=0;
        if(p==t) return f[s][t]=1;
        for(int i=g[t];~i;i=next[i]) sum+=dp(p,v[i]);
        sum+=dp(p,t);
        return f[s][t]=sum/(deg[t]+1)+1;
    }
    
    int main() {
        memset(g,-1,sizeof(g));
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for(int i=1,a,b;i<=m;i++) {
            scanf("%d%d",&a,&b);
            addedge(a,b);
        }
        for(int i=1;i<=n;i++) spfa(i);
        
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) f[i][j]=-1;
            f[i][i]=0;    
        }
        printf("%.3lf
    ",dp(s,t));
        return 0;
    }
  • 相关阅读:
    装饰器
    kolla部署all-in-one
    k8s集群部署gitlab
    helm部署gitlab
    控制器和pod调度流程
    esxi安装
    Linux系统性能分析工具
    configMap和secret
    etcd 问题、调优、监控
    动感单车
  • 原文地址:https://www.cnblogs.com/invoid/p/5632808.html
Copyright © 2011-2022 走看看