zoukankan      html  css  js  c++  java
  • P3232[HNOI2013]游走

    题意

    给定一个 nnn 个点 mmm 条边的无向连通图,顶点从 111 编号到 nnn,边从 111 编号到 mmm。

    小 Z 在该图上进行随机游走,初始时小 Z 在 111 号顶点,每一步小 Z 以相等的概率随机选择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小 Z 到达 nnn 号顶点时游走结束,总分为所有获得的分数之和。 现在,请你对这 mmm 条边进行编号,使得小 Z 获得的总分的期望值最小。

    思路

    因为路径中有环,所以不能直接递推,所以要先把期望的式子列出来,再进行高斯消元求解,求完解后,按期望大小进行排序,期望次数 大的就有小的标号,小的用大的标号,依次后求出答案

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int du[503],num,head[503];
    double b[503],f[250004];
    double g[505][505],x[503];
    struct{
        int ne,to,w;
    }a[250004];
    void lian(int from,int to){
        num++;
        a[num].ne=head[from];
        a[num].to=to;
        head[from]=num;
    }
    void guss(int n){
        int i,j,k,Max;
        double p;
        for(i=1;i<=n;i++){
            Max=i;
            for(j=i+1;j<=n;j++)
                if(fabs(g[Max][i])<fabs(g[j][i]))Max=j;
            for(j=i;j<=n;j++)
                swap(g[i][j],g[Max][j]);
            swap(b[i],b[Max]);
            for(j=1;j<=n;j++)if(i!=j&&g[j][i]!=0){
                p=g[j][i]/g[i][i];b[j]-=b[i]*p;
                for(k=1;k<=n;k++)
                    g[j][k]-=g[i][k]*p;
            }
        }
    }
    int main(){
        int n,m,to,i,j,u,v,w,from;
        double ans=0;
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            lian(u,v);lian(v,u);
            du[u]++;du[v]++;
        }
        for(i=1;i<n;i++){
            g[i][i]=1;
            for(j=head[i];j;j=a[j].ne){
                to=a[j].to;
                if(to!=n)g[i][to]=-1.0/du[to];
            }
        }b[1]=1;
        guss(n-1);
        for(i=1;i<n;i++){
            if(g[i][i]!=0)x[i]=b[i]/g[i][i];
        //    cout<<du[i]<<" ";
        }
    //    for(i=1;i<=n;i++)
        //    for(j=1;j<=n;j++)cout<<g[i][j]<<" ";
        for(i=2;i<=num;i+=2){
            to=a[i].to;from=a[i-1].to;
            if(to!=n)f[i/2]=x[to]/du[to];
            if(from!=n)f[i/2]+=x[from]/du[from];
        }
        sort(f+1,f+num/2+1);
        for(i=1;i<=num/2;i++)
            ans+=f[i]*(num/2-i+1);
        printf("%.3lf
    ",ans);
        return 0;
    }
  • 相关阅读:
    HDU 5273 Dylans loves sequence 暴力递推
    HDU 5285 wyh2000 and pupil 判二分图+贪心
    HDU 5281 Senior's Gun 贪心
    HDU 5651 xiaoxin juju needs help 逆元
    HDU 5646 DZY Loves Partition
    HDU 5366 The mook jong
    HDU 5391Z ball in Tina Town 数论
    HDU 5418 Victor and World 允许多次经过的TSP
    HDU 5642 King's Order dp
    抽屉原理
  • 原文地址:https://www.cnblogs.com/Jessica-Cao/p/14002138.html
Copyright © 2011-2022 走看看