bzoj3143 游走

Description

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

Input

第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。

Output

仅包含一个实数,表示最小的期望值,保留3位小数。

每个点i走到的期望次数x[i]=(i==1?1:0)+sigma(x[j]/o[j]) (j!=n , i到j有边)

o[j]为j的度

高斯消元解出每个x[i]

边(a,b)走过的期望次数为(a==n?0:x[a]/o[a])+(b==n?0:x[b]/o[b])

按边走过的次数从大到小排序并顺序编号

#include<cstdio>
#include<vector>
#include<algorithm>
int n,m,a,b;
std::vector<int>es[512];
double xs[512][512],ys[512],x[512],ans=0;
int o[512];
inline bool is0(double x){return x<1.0e-10&&x>-1.0e-10;}
inline bool isn0(double x){return x>=1.0e-10||x<=-1.0e-10;}
struct edge{
    int a,b;
    double v;
}e[250000];
int ep=0;
bool operator<(edge a,edge b){
    return a.v>b.v;
}
int main(){
    scanf("%d%d",&n,&m);
    while(m--){
        scanf("%d%d",&a,&b);
        es[a].push_back(b);
        es[b].push_back(a);
        o[a]++;o[b]++;
        e[ep].a=a;e[ep++].b=b;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)xs[i][j]=0;
        xs[i][i]=-1;
        for(int j=0;j<es[i].size();j++){
            int u=es[i][j];
            if(u!=n)xs[i][u]+=1.0/o[u];
        }
        ys[i]=0;
    }
    ys[1]=-1;
    for(int t=1;t<=n;t++){
        if(is0(xs[t][t]))
        for(int i=t+1;i<=n;i++){
            if(isn0(xs[i][t])){
                for(int j=t;j<=n;j++){double v=xs[i][j];xs[i][j]=xs[t][j];xs[t][j]=v;}
                double v=ys[i];ys[i]=ys[t];ys[t]=v;
            }
        }
        double c=1.0/xs[t][t];
        for(int i=t;i<=n;i++)xs[t][i]*=c;
        ys[t]*=c;
        for(int i=t+1;i<=n;i++){
            if(isn0(xs[i][t])){
                double k=xs[i][t];
                for(int j=t;j<=n;j++){
                    xs[i][j]-=xs[t][j]*k;
                }
                ys[i]-=ys[t]*k;
            }
        }
    }
    for(int t=n;t;t--){
        for(int i=t+1;i<=n;i++){
            ys[t]-=xs[t][i]*x[i];
        }
        x[t]=ys[t];
    }
    for(int i=0;i<ep;i++){
        e[i].v=0;
        if(e[i].a!=n)e[i].v+=x[e[i].a]/o[e[i].a];
        if(e[i].b!=n)e[i].v+=x[e[i].b]/o[e[i].b];
    }
    std::sort(e,e+ep);
    for(int i=0;i<ep;i++)ans+=e[i].v*(i+1);
    printf("%.3lf\n",ans);
    return 0;
}
时间: 2024-10-13 00:05:24

bzoj3143 游走的相关文章

bzoj3143 游走 概率 高斯消元

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3143 题目大意是说:给出一张无向图,找出一种加权值的方式,使得从1到n期望带权路径长度最短,输出最短路长度. 首先,根据基本常识,走的次数多的边,权值越小越好(废话). 于是问题转变为:找出每条边的期望经过次数. 设i边期望经过次数为f[i],则f[i]就为两个端点期望经过次数与走到这条边概率之商的和(没看懂?就是f[i]=x[duan1]/du[duan1]+x[duan2]/du[dua

bzoj3143游走

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3143 学到了无向图中点被经过的期望次数和边被经过的期望次数. 一个点被经过的期望次数  就是  与它相连的点被经过的期望次数/那个点的度数  的求和. https://www.cnblogs.com/owenyu/p/6724721.html这个博客说的很好. 该博客让我受到的启发就是一个点被经过的期望次数是依赖于与它相连的点的,可是要算它的时候相连点还没算出来,算相连点又要用到它的数据,

【BZOJ3143】[Hnoi2013]游走 期望DP+高斯消元

[BZOJ3143][Hnoi2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. Input 第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v

bzoj3143 [Hnoi2013]游走

Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. Input 第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边. 输

BZOJ3143 - HNOI2013游走【高斯消元】

Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. Input 第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边. 输

【BZOJ-3143】游走 高斯消元 + 概率期望

3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2264  Solved: 987[Submit][Status][Discuss] Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数

bzoj3143【HNOI2013】游走

3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1962  Solved: 874 [Submit][Status][Discuss] Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的

【BZOJ3143】[Hnoi2013]游走

一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. 期望次数大的标号应该小 p[e] = p[e.x] / out[e.x] + p[e.y] / out[e.y] 剩下的和3270相同 #include <iostream

bzoj3143 luogu3232 游走

3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4289  Solved: 2008[Submit][Status][Discuss] Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分