zoukankan      html  css  js  c++  java
  • BZOJ1415: [Noi2005]聪聪和可可

    题目描述

    在一个魔法森林里,住着一只聪明的小猫聪聪和一只可爱的小老鼠可可。虽 然灰姑娘非常喜欢她们俩,但是,聪聪终究是一只猫,而可可终究是一只老鼠, 同样不变的是,聪聪成天想着要吃掉可可。

    一天,聪聪意外得到了一台非常有用的机器,据说是叫 GPS,对可可能准确 的定位。有了这台机器,聪聪要吃可可就易如反掌了。于是,聪聪准备马上出发, 去找可可。而可怜的可可还不知道大难即将临头,仍在森林里无忧无虑的玩耍。 小兔子乖乖听到这件事,马上向灰姑娘报告。灰姑娘决定尽快阻止聪聪,拯救可 可,可她不知道还有没有足够的时间。

    整个森林可以认为是一个无向图,图中有 NNN 个美丽的景点,景点从 111 至 NNN 编号。小动物们都只在景点休息、玩耍。在景点之间有一些路连接。

    当聪聪得到 GPS 时,可可正在景点 MMM(M≤NM≤NMN)处。以后的每个时间单位,可可 都会选择去相邻的景点(可能有多个)中的一个或停留在原景点不动。而去这些地方所发生的概率是相等的。假设有 PPP 个景点与景点 M 相邻,它们分别是景点 R、 景点 S,……景点 Q,在时刻 TTT 可可处在景点 M,则在( T+1 T+1 T+1 )时刻,可可有 1/(1+P)1/(1 +P)1/(1+P) 的可能在景点 R,有 1/(1+P)1/(1 +P)1/(1+P) 的可能在景点 S,……,有 1/(1+P)1/(1 +P)1/(1+P) 的可能在景点 Q,还有1/(1+P)1/(1 +P)1/(1+P)的可能停在景点 M

    我们知道,聪聪是很聪明的,所以,当她在景点 C 时,她会选一个更靠近 可可的景点,如果这样的景点有多个,她会选一个标号最小的景点。由于聪聪太 想吃掉可可了,如果走完第一步以后仍然没吃到可可,她还可以在本段时间内再 向可可走近一步。

    在每个时间单位,假设聪聪先走,可可后走。在某一时刻,若聪聪和可可位 于同一个景点,则可怜的可可就被吃掉了。

    灰姑娘想知道,平均情况下,聪聪几步就可能吃到可可。而你需要帮助灰姑 娘尽快的找到答案。

    输入输出格式

    输入格式:

    数据的第 1 行为两个整数 NNN 和 EEE,以空格分隔,分别表示森林中的景点数和 连接相邻景点的路的条数。

    第 2 行包含两个整数 CCC 和 MMM,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号。

    接下来 E 行,每行两个整数,第 i+2i+2i+2 行的两个整数 AiA_iAiBiB_iBi表示景点 AiA_iAi和景点 BiB_iBi 之间有一条路。 所有的路都是无向的,即:如果能从 A 走到 B,就可以从 B 走到 A。

    输入保证任何两个景点之间不会有多于一条路直接相连,且聪聪和可可之间必有路直接或间接的相连。

    输出格式:

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

    【输入样例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

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

    解题思路:

    本来算了一下时间,应该是一个遍历的复杂度,大概是可以忍受的,即使再差,最差也是配对的时间复杂度。

    然后卡在了建图。

    floyd稳定O(n3)想都不用想。

    然后我就被卡死了。

    回头再看一下数据范围,点数边数很接近诶。

    据说Spfa处理稀疏图有奇效。不过Spfa不是死了吗。

    这不是05年嘛。

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 struct pnt{
      6     int hd;
      7     int no;
      8     double dp[1001];
      9     double num;
     10     int dis[1001];
     11     int nxt[1001];
     12     bool hvn[1001];
     13     bool in;
     14     bool vis[1001];
     15 }p[1001];
     16 struct ent{
     17     int twd;
     18     int lst;
     19 }e[100000];
     20 int n,m;
     21 int cnt;
     22 int cc,kk;
     23 std::queue<int>Q;
     24 void ade(int f,int t)
     25 {
     26     cnt++;
     27     e[cnt].twd=t;
     28     e[cnt].lst=p[f].hd;
     29     p[f].hd=cnt;
     30     return ;
     31 }
     32 void Spfa(int x)
     33 {
     34     for(int i=1;i<=n;i++)
     35     {
     36         p[i].in=0;
     37         p[x].dis[i]=0x3f3f3f3f;
     38         p[x].nxt[i]=0x3f3f3f3f;
     39     }
     40     p[x].dis[x]=0;
     41     p[x].in=1;
     42     Q.push(x);
     43     while(!Q.empty())
     44     {
     45         int s=Q.front();
     46         Q.pop();
     47         p[s].in=false;
     48         for(int i=p[s].hd;i;i=e[i].lst)
     49         {
     50             int to=e[i].twd;
     51             if(p[x].dis[to]>p[x].dis[s]+1)
     52             {
     53                 p[x].dis[to]=p[x].dis[s]+1;
     54                 if(!p[to].in)
     55                     Q.push(to);
     56                 p[to].in=true;
     57             }
     58         }
     59     }
     60     return ;
     61 }
     62 double Dp(int killer,int deserter)
     63 {
     64     if(p[killer].vis[deserter])
     65         return p[killer].dp[deserter];
     66     if(deserter==killer)
     67     {
     68         p[killer].dp[deserter]=0.00;
     69         p[killer].dp[deserter]=true;
     70         return 0.00;
     71     }
     72     int kl=killer;
     73     killer=p[killer].nxt[deserter];
     74     if(killer==deserter)
     75         return 1.00;
     76     killer=p[killer].nxt[deserter];
     77     if(killer==deserter)
     78         return 1.00;
     79     p[kl].dp[deserter]=(1.00/p[deserter].num)*(1.00+Dp(killer,deserter));
     80     for(int i=p[deserter].hd;i;i=e[i].lst)
     81     {
     82         int to=e[i].twd;
     83         p[kl].dp[deserter]+=(1.00/p[deserter].num)*(1.00+Dp(killer,to));
     84     }
     85     
     86     p[kl].vis[deserter]=true;
     87     return p[kl].dp[deserter];
     88 }
     89 int main()
     90 {
     91     scanf("%d%d%d%d",&n,&m,&cc,&kk);
     92     for(int i=1;i<=n;i++)
     93     {
     94         p[i].no=i;
     95         p[i].num=1.00;
     96     }
     97     for(int i=1;i<=m;i++)
     98     {
     99         int a,b;
    100         scanf("%d%d",&a,&b);
    101         p[a].dp[b]=p[b].dp[a]=1.00;
    102         p[a].vis[b]=p[b].vis[a]=true;
    103         ade(a,b);
    104         ade(b,a);
    105         p[a].num+=1.00;
    106         p[b].num+=1.00;
    107     }
    108     for(int i=1;i<=n;i++)
    109         Spfa(i);
    110     for(int x=1;x<=n;x++)
    111         for(int i=p[x].hd;i;i=e[i].lst)
    112         {
    113             int to=e[i].twd;
    114             for(int j=1;j<=n;j++)
    115                 if(p[to].dis[j]+1==p[x].dis[j])
    116                     p[x].nxt[j]=std::min(to,p[x].nxt[j]);
    117         }
    118     printf("%.3lf
    ",Dp(cc,kk));
    119     return 0;
    120 }
  • 相关阅读:
    AtCoder Beginner Contest 205
    Codeforces Round #725 (Div. 3)
    Educational Codeforces Round 110 (Rated for Div. 2)【A
    Codeforces Round #722 (Div. 2)
    AtCoder Beginner Contest 203(Sponsored by Panasonic)
    AISing Programming Contest 2021(AtCoder Beginner Contest 202)
    PTA 520 钻石争霸赛 2021
    Educational Codeforces Round 109 (Rated for Div. 2)【ABCD】
    AtCoder Beginner Contest 200 E
    Educational Codeforces Round 108 (Rated for Div. 2)【ABCD】
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9743925.html
Copyright © 2011-2022 走看看