zoukankan      html  css  js  c++  java
  • [补档][Hnoi2013]游走

    [Hnoi2013]游走

    题目

    一个无向连通图,顶点从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位小数。

    SAMPLE

    INPUT

    3 3
    2 3
    1 2
    1 3

    OUTPUT

    3.333

    解题报告

    这东西显然是个概率与期望(题目写的那么清楚啊喂),好吧,是一个很裸的概率与期望。
    题目要求总分最小,且编号从1到m,那么显然,我们需要求一下每条边被经过的期望,期望越大,编号越小。
    首先自然能删除终点的所有出边(终点是不能出来的),然后,对于每一条边,设两端端点为u,v,我们可以从u走到v,也可以从v走到u,从u走到v的期望次数等于

    经过点u的次数/u的度

    问题自然就转化成求每个点的期望经过次数,对于起点来说,一开始一定会经过一次,在之后也可能被经过。

    f[1]=1+sigma(f[j]/degree[j],j和1有边相连)

    f[i]=sigma(f[j]/degree[j],i与j有边相连)

    我们得到了n变量n方程的方程组,然后高斯消元乱抡= =
    稍微处理下就可以得到经过每个点的期望,那么每条边的期望即为两端点期望之和(注意:对终点一定要特殊处理啊啊啊),对每条边按期望排序,随便一乘,一加,就可以AC了。
      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 using namespace std;
      6 inline int read(){
      7     int sum(0);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar());
     10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     11     return sum;
     12 }
     13 struct edge{
     14     int s,e,n;
     15 }ed[250001];
     16 int pre[501],tot;
     17 inline void insert(int s,int e){
     18     ed[++tot].s=s;
     19     ed[tot].e=e;
     20     ed[tot].n=pre[s];
     21     pre[s]=tot;
     22 }
     23 int du[501];
     24 int n,m;
     25 double a[501][501],b[501],ans[501];
     26 inline double jdz(double x){
     27     return x>=0?x:-x;
     28 }
     29 inline void swp(double &a,double &b){
     30     double c(a);
     31     a=b;
     32     b=c;
     33 }
     34 inline void gauss(){
     35     int num,cnt(1);
     36     for(int i=1;i<n;i++,cnt++){
     37         num=i;
     38         for(int j=i+1;j<=n;j++)
     39             if(jdz(a[num][i])<jdz(a[j][i]))
     40                 num=j;
     41         if(num!=i){
     42             for(int j=1;j<=n;j++)
     43                 swp(a[num][j],a[cnt][j]);
     44             swp(b[num],b[cnt]);
     45         }
     46         if(!a[cnt][i]){
     47             cnt--;
     48             continue;
     49         }
     50         for(int j=cnt+1;j<=n;j++){
     51             double t(a[j][i]/a[cnt][i]);
     52             for(int k=i;k<=n;k++)
     53                 a[j][k]-=t*a[i][k];
     54             b[j]-=t*b[i];
     55         }
     56     }
     57     for(int i=n;i>0;i--){
     58         for(int j=n;j>i;j--)
     59             b[i]-=a[i][j]*ans[j];
     60         ans[i]=b[i]/a[i][i];
     61     }
     62 }
     63 double f[250001];
     64 bool g[501][501];
     65 inline int gg(){
     66 //  freopen("walk.in","r",stdin);
     67 //  freopen("walk.out","w",stdout);
     68     n=read(),m=read();
     69     for(int i=1;i<=m;i++){
     70         int x(read()),y(read());
     71         insert(x,y);
     72         g[x][y]=g[y][x]=1;
     73         du[x]++,du[y]++;
     74     }
     75     du[n]=0;
     76     for(int i=1;i<=n;i++){
     77         if(i==1)
     78             b[i]=1;
     79         else
     80             b[i]=0;
     81         for(int j=1;j<=n;j++){
     82             if(i==j){
     83                 a[i][j]=1;
     84                 continue;
     85             }
     86             if(j==n){
     87                 a[i][j]=0;
     88                 continue;
     89             }
     90             if(g[i][j])
     91                 a[i][j]=-1.0/(double)du[j];
     92         }
     93     }
     94     gauss();
     95     for(int i=1;i<n;i++)
     96         ans[i]/=du[i];
     97     ans[n]=0;
     98     for(int i=1;i<=tot;i++){
     99         int s(ed[i].s),e(ed[i].e);
    100         f[i]=ans[s]+ans[e];
    101     }
    102     int cnt(tot);
    103     sort(f+1,f+tot+1);
    104     double an(0);
    105     for(int i=1;i<=tot;i++)
    106         an+=i*f[cnt--];
    107     printf("%.3lf",an);
    108     return 0;
    109 }
    110 int k(gg());
    111 int main(){;}
    View Code
    ps:COGS rk1代码奉上,虽然榜貌似被两个神奇的(hhh)刷成(hhh)了,但是还是没有什么影响。。。
  • 相关阅读:
    windows本地提权——2003笔记
    Windows与linux添加用户命令
    反弹shell集锦
    提权-特权升级
    常见端口
    git泄露利用脚本
    Thinkphp5命令执行利用
    Thinkphp2.1漏洞利用
    打ms15-034补丁出现“此更新 不适用于您的计算机”
    Hyda爆破
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7276010.html
Copyright © 2011-2022 走看看