zoukankan      html  css  js  c++  java
  • 【Hnoi2013】Bzoj3143 游走

    Position:


    List

    Description

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

    xSolution

    整体理解:a[i][j]表示从i号点走到j号点概率次数。由于走到n不走了,故a[n][i]=0。i→i为-1。初始值a[1][n+1]=-1,代表从1号点出发次数为1。然后Gauss消元求出每个点的期望经过次数,那么对于一条边ei,它的期望经过次数就为e[i]=a[u[i]][n+1]/d[u[i]]+a[v[i]][n+1]/d[v[i]],将边的期望经过次数排序,根据贪心思想,次数多的边赋小值答案更优,ans=e[i]*(m-i+1)。
    模板:高斯消元还是第一次写,O(n^3)。
    深入理解:每一个未知数代表从这个点到达的次数,用它/出度即为对与它相邻边贡献。考虑一个点,到达次数f[i]=∑f[from]/d[from],移到左边-f[i]+∑f[from]/d[from]=0,特殊的,对于第一个点次数右边等于-1,即开始从这里出发,次数为1。对于第n个点,有点奇怪,到这个点的次数为0,这样是为了满足条件到了n号点,就不会出去了,不会对其它点的值造成影响,而最后也不是要求每个点到达次数期望。而是每条边的次数,而n也不会对与其相连的边的期望次数造成影响,所以Accept。

    Code

    // <hang.cpp> - 08/01/16 15:30:38
    // This file is made by YJinpeng,created by XuYike's black technology automatically.
    // Copyright (C) 2016 ChangJun High School, Inc.
    // I don't know what this program is.
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #define MOD 1000000007
    #define EPS 1e-10 
    #define INF 1e9
    using namespace std;
    typedef long long LL;
    const int MAXN=510;
    const int MAXM=100010;
    inline int max(int &x,int &y) {return x>y?x:y;}
    inline int min(int &x,int &y) {return x<y?x:y;}
    inline int getint() {
        register int w=0,q=0;register char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')q=1,ch=getchar();
        while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
        return q?-w:w;
    }
    double ans;
    int n,m,d[MAXN],u[MAXN*MAXN],v[MAXN*MAXN];
    double a[MAXN][MAXN],e[MAXN*MAXN];
    void Gauss(){
        for(int i=1;i<=n;i++){
            for(int k=i+1;k<=n;k++)if(fabs(a[k][i])>fabs(a[i][i]))swap(a[k],a[i]);
            for(int j=n+1;j>=i;j--)a[i][j]/=a[i][i];
            for(int k=i+1;k<=n;k++)
                for(int j=n+1;j>=i;j--)a[k][j]-=a[k][i]*a[i][j];
        }
        for(int i=n;i;i--)
            for(int k=i-1;k;k--)a[k][n+1]-=a[k][i]*a[i][n+1];
    }
    int main()
    {
        freopen("hang.in","r",stdin);
        freopen("hang.out","w",stdout);
        n=getint();m=getint();
        for(int i=1;i<=m;i++){
            u[i]=getint();v[i]=getint();
            d[u[i]]++;d[v[i]]++;
        }
        for(int i=1;i<=m;i++){
            a[u[i]][v[i]]+=1.0/d[v[i]];
            a[v[i]][u[i]]+=1.0/d[u[i]];
        }
        for(int i=1;i<=n;i++)a[n][i]=0,a[i][i]=-1;
        a[1][n+1]=-1;ans=0;Gauss();
        for(int i=1;i<=m;i++)e[i]=a[u[i]][n+1]/d[u[i]]+a[v[i]][n+1]/d[v[i]];
        sort(e+1,e+1+m);
        for(int i=1;i<=m;i++)ans+=e[i]*(m-i+1);
        printf("%.3f
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    css 元素垂直居中
    win7定时关机
    tabel使用总结
    Js获取当前日期时间及其它操作
    织梦dedecms自定义表单设置必填项
    css字体文本格式 鼠标样式
    css溢出文本显示省略号
    java注解学习
    自定义JSON返回字段
    Spring-解决请求中文乱码问题
  • 原文地址:https://www.cnblogs.com/YJinpeng/p/5907208.html
Copyright © 2011-2022 走看看