• Bzoj1415 [Noi2005]聪聪和可可


    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1586  Solved: 929

    Description

    Input

    数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数。 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号。 接下来E行,每行两个整数,第i+2行的两个整数Ai和Bi表示景点Ai和景点Bi之间有一条路。 所有的路都是无向的,即:如果能从A走到B,就可以从B走到A。 输入保证任何两个景点之间不会有多于一条路直接相连,且聪聪和可可之间必有路直接或间接的相连。

    Output

    输出1个实数,四舍五入保留三位小数,表示平均多少个时间单位后聪聪会把可可吃掉。

    Sample Input

    【输入样例1】
    4 3
    1 4
    1 2
    2 3
    3 4
    【输入样例2】
    9 9
    9 3
    1 2
    2 3
    3 4
    4 5
    3 6
    4 6
    4 7
    7 8
    8 9

    Sample Output

    【输出样例1】
    1.500
    【输出样例2】
    2.167

    HINT

    【样例说明1】
    开始时,聪聪和可可分别在景点1和景点4。
    第一个时刻,聪聪先走,她向更靠近可可(景点4)的景点走动,走到景点2,然后走到景点3;假定忽略走路所花时间。
    可可后走,有两种可能:
    第一种是走到景点3,这样聪聪和可可到达同一个景点,可可被吃掉,步数为1,概率为 。
    第二种是停在景点4,不被吃掉。概率为 。
    到第二个时刻,聪聪向更靠近可可(景点4)的景点走动,只需要走一步即和可可在同一景点。因此这种情况下聪聪会在两步吃掉可可。
    所以平均的步数是1* +2* =1.5步。


    对于所有的数据,1≤N,E≤1000。
    对于50%的数据,1≤N≤50。

    Source

    题目所求的“期望步数”应该理解成期望次数,也就是说一回合走两步算成一步

    ↑样例也说明了这一点

    Spfa/BFS预处理出从聪聪一个点到另一个点所走的方向,剩下的就是一个记忆化期望DP了。

    方程还算简单。

    注意第49行,如果不加nxt[nxt[x][y]][y]==y判断的话,是不能贪心每次走两步的。

    (灵魂画师在此)

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #include<queue>
     9 using namespace std;
    10 const double eps=1e-7;
    11 const int mxn=1010;
    12 int read(){
    13     int x=0,f=1;char ch=getchar();
    14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 struct edge{
    19     int v,nxt;
    20 }e[200010];
    21 int hd[mxn],mct=0;
    22 void add_edge(int u,int v){
    23     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
    24 }
    25 int dis[mxn];
    26 int nxt[mxn][mxn];
    27 void BFS(int s){
    28     memset(dis,0x3f,sizeof dis);
    29     queue<int>q;
    30     q.push(s);dis[s]=0;
    31     nxt[s][s]=s;
    32     while(!q.empty()){
    33         int u=q.front(),v;q.pop();
    34         for(int i=hd[u];i;i=e[i].nxt){
    35             v=e[i].v;
    36             if(dis[v]>dis[u]+1 || (dis[v]==dis[u]+1 && u<nxt[v][s])){
    37                 nxt[v][s]=u;
    38                 dis[v]=dis[u]+1;
    39                 q.push(v);
    40             }
    41         }
    42     }
    43     return;
    44 }
    45 int out[mxn];
    46 double f[mxn][mxn];
    47 double DFS(int x,int y){
    48     if(x==y)return f[x][y]=0;
    49     if(nxt[x][y]==y || nxt[nxt[x][y]][y]==y)return f[x][y]=1;
    50     if(abs(f[x][y])>eps)return f[x][y];
    51     double res=0;double f1=0;
    52     for(int i=hd[y],v;i;i=e[i].nxt){//老鼠可能的去向 
    53         v=e[i].v;f1+=DFS(nxt[nxt[x][y]][y],v);
    54     }
    55     f1+=DFS(nxt[nxt[x][y]][y],y);//老鼠不动 
    56     res=f1/(out[y]+1)+1;
    57     return f[x][y]=res;
    58 }
    59 int n,E,C,M;
    60 int main(){
    61 //    freopen("in.txt","r",stdin);
    62     int i,j,u,v;
    63     n=read();E=read();
    64     C=read();M=read();
    65     for(i=1;i<=E;i++){
    66         u=read();v=read();
    67         add_edge(u,v);
    68         add_edge(v,u);
    69         out[u]++;out[v]++;
    70     }
    71     for(i=1;i<=n;i++)BFS(i);
    72     DFS(C,M);
    73     printf("%.3f
    ",f[C][M]);
    74     return 0;
    75 }
  • 相关阅读:
    AUDIT审计的一些使用
    HOW TO PERFORM BLOCK MEDIA RECOVERY (BMR) WHEN BACKUPS ARE NOT TAKEN BY RMAN. (Doc ID 342972.1)
    使用BBED理解和修改Oracle数据块
    Using Class of Secure Transport (COST) to Restrict Instance Registration in Oracle RAC [ID 1340831.1]
    调试利器GDB概念
    第4章 思科IOS
    第3章 ip地址和子网划分
    第2章 TCPIP
    2020年阅读过的黑客资源推荐篇
    第1章 计算机网络
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6591805.html
Copyright © 2020-2023  润新知