zoukankan      html  css  js  c++  java
  • 【BZOJ】3143: [Hnoi2013]游走

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3143


    显然如果一条边期望被走过的次数越多,我们就应该给它的编号越小。

    所以问题变为如何求每一条边被经过的期望次数

    考虑直接求边的期望有点困难。

    设:${g[i]}$表示经过第$i$条边的期望次数,${f[i]}$表示经过第$i$个点的期望次数,${du[i]}$表示第$i$个点的度数。

    对于一条边$i$,假设这条边的两段的点分别为${x,y}$,则${g[i]=frac{f[x]}{du[x]}*frac{f[y]}{du[y]}}$

    所以问题变为如何求每一个点被经过的期望次数

    设$e[x][y]$表示点$x,y$之间有连边。这就很裸了,${f[i]=sum (frac{f[x]}{du[x]}left [ e[i][x]=1 ight ] )}$,其中$n$号点只能走进去而不能出来,所以忽略不管,$1$号点应当强制$+1$(因为一开始就从$1$号点开始)

    这样就得到了一个$n-1$个未知数和$n-1$个式子的方程组,高斯消元求得每个未知数的解(即${f[i]}$),然后求出${g[i]}$,然后从大到小排序。

    $${sum _{i=1}^{m}g[i]*i}$$


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 510
    10 #define llg long long 
    11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    12 llg n,m;
    13 double a[maxn][maxn],du[maxn],f[maxn],g[maxn*maxn];
    14 
    15 struct Edge{llg x,y;}e[maxn*maxn];
    16 
    17 bool cmp(double x,double y){return x>y;}
    18 
    19 void guass()
    20 {
    21     llg r;
    22     for (llg i=1;i<=n;i++)
    23     {
    24         r=i;
    25         for (llg j=i+1;j<=n;j++) if (fabs(a[j][i])>fabs(a[r][i])) r=j;
    26         if (r!=i) for (llg j=1;j<=n+1;j++) swap(a[r][j],a[i][j]);
    27 
    28         for (llg k=i+1;k<=n;k++)
    29         {
    30             double F=a[k][i]/a[i][i];
    31             for (llg j=i;j<=n+1;j++) a[k][j]-=F*a[i][j];
    32         }
    33     }
    34 
    35     for (llg i=n;i>=1;i--)
    36     {
    37         for (llg j=i+1;j<=n;j++) a[i][n+1]-=f[j]*a[i][j];
    38         f[i]=a[i][n+1]/a[i][i];
    39     }
    40 }
    41 
    42 void init()
    43 {
    44     llg x,y;
    45     cin>>n>>m;
    46     for (llg i=1;i<=m;i++)
    47     {
    48         scanf("%lld%lld",&e[i].x,&e[i].y);
    49         du[e[i].x]++,du[e[i].y]++;
    50     }
    51     for (llg i=1;i<=m;i++)
    52     {
    53         x=e[i].x,y=e[i].y;
    54         if (y!=n) {a[x][y]=1.00/du[y];}
    55         if (x!=n) {a[y][x]=1.00/du[x];}
    56     }
    57     for (llg i=1;i<n;i++) a[i][i]=-1;
    58     a[1][n]=-1;
    59     n--;
    60 }
    61 
    62 int main()
    63 {
    64     yyj("walk");
    65     init();
    66     guass();
    67     for (llg i=1;i<=m;i++) g[i]=f[e[i].x]/du[e[i].x]+f[e[i].y]/du[e[i].y];
    68     double ans=0;
    69     sort(g+1,g+m+1,cmp);
    70     for (llg i=1;i<=m;i++) ans+=(double)i*g[i];
    71     printf("%.3lf",ans);
    72     return 0;
    73 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    深入学习高级非线性回归算法 --- 树回归系列算法
    监督学习中关于线性回归问题的系统讨论
    非均衡分类问题的思考与问题与解决思路
    使用 AdaBoost 元算法提高分类器性能
    支持向量机 (SVM)分类器原理分析与基本应用
    Logistic回归分类算法原理分析与代码实现
    mysql 数据库安装步骤个人总结
    mysql可重复读现象及原理分析
    ssm所需的jar详解
    获取客户端ip地址--getRemoteAddr()和getRemoteHost() 区别
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6433272.html
Copyright © 2011-2022 走看看