• 洛谷P4206 聪聪与可可


    无向简单图上给定s,t。每秒s先向t按照最短路走两步(优先节点编号较小的),然后t随机行动一步。

    问期望多少秒相遇。n <= 1000

    解:

    这个s太蛇皮了...所以预处理一波。

    然后不会,看题解发现是SB记忆化搜索......

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 1010;
      4 const double eps = 1e-13;
      5 
      6 struct Edge {
      7     int nex, v;
      8 }edge[N << 1]; int tp;
      9 
     10 int e[N], gt[N][N], n, m, fr[N], d[N], vis[N], in[N], frfr[N];
     11 double f[N][N];
     12 std::queue<int> Q;
     13 
     14 inline void add(int x, int y) {
     15     tp++;
     16     edge[tp].v = y;
     17     edge[tp].nex = e[x];
     18     e[x] = tp;
     19     return;
     20 }
     21 
     22 void DFS(int x, int s) {
     23     for(int i = e[x]; i; i = edge[i].nex) {
     24         int y = edge[i].v;
     25         if(fr[y] == x) {
     26             gt[s][y] = gt[s][x];
     27             DFS(y, s);
     28         }
     29     }
     30     return;
     31 }
     32 
     33 inline void BFS(int s) {
     34     Q.push(s);
     35     vis[s] = s;
     36     d[s] = 0;
     37     fr[s] = 0; frfr[s] = 0;
     38     while(Q.size()) {
     39         int x = Q.front();
     40         Q.pop();
     41         for(int i = e[x]; i; i = edge[i].nex) {
     42             int y = edge[i].v;
     43             if(vis[y] != s) {
     44                 vis[y] = s;
     45                 d[y] = d[x] + 1;
     46                 fr[y] = x;
     47                 frfr[y] = (x == s) ? y : frfr[x];
     48                 Q.push(y);
     49             }
     50             else if(d[y] == d[x] + 1) {
     51                 if(frfr[x] < frfr[y]) {
     52                     frfr[y] = frfr[x];
     53                     fr[y] = x;
     54                 }
     55             }
     56         }
     57     }
     58     /// get gt
     59     gt[s][s] = s; f[s][s] = 0;
     60     for(int i = e[s]; i; i = edge[i].nex) {
     61         int y = edge[i].v;
     62         gt[s][y] = y;
     63         DFS(y, s);
     64     }
     65     return;
     66 }
     67 
     68 double F(int x, int y) {
     69     if(f[x][y] >= -eps) {
     70         return f[x][y];
     71     }
     72     if(gt[x][y] == y || gt[gt[x][y]][y] == y) {
     73         return f[x][y] = 1;
     74     }
     75     double ans = 0;
     76 
     77     int z = gt[gt[x][y]][y];
     78     for(int i = e[y]; i; i = edge[i].nex) {
     79         int w = edge[i].v;
     80         ans += F(z, w);
     81     }
     82     ans += F(z, y);
     83 
     84     return f[x][y] = ans / (in[y] + 1) + 1;
     85 }
     86 
     87 int main() {
     88     int s, t;
     89     scanf("%d%d", &n, &m);
     90     scanf("%d%d", &s, &t);
     91     for(int i = 1, x, y; i <= m; i++) {
     92         scanf("%d%d", &x, &y);
     93         add(x, y); add(y, x);
     94         in[x]++; in[y]++;
     95     }
     96 
     97     for(int i = 1; i <= n; i++) {
     98         for(int j = 1; j <= n; j++) {
     99             f[i][j] = -1;
    100         }
    101     }
    102 
    103     for(int i = 1; i <= n; i++) {
    104         BFS(i);
    105     }
    106 
    107     /*printf("-----------
    ");
    108     for(int i = 1; i <= n; i++) {
    109         for(int j = 1; j <= n; j++) {
    110             printf("%d ", gt[i][j]);
    111         }
    112         printf("
    ");
    113     }
    114     printf("-----------
    ");
    115     */
    116 
    117     printf("%.3f
    ", F(s, t));
    118     return 0;
    119 }
    AC代码

    感觉不会死循环的原因是每次之后s和t的距离至少减少1,至多减少3。按s和t的距离分层的话每一步都走到了不同的层。

  • 相关阅读:
    Java实现币值最大化问题
    Java实现币值最大化问题
    Java实现币值最大化问题
    Java实现币值最大化问题
    ddd
    雷军:小米最坏的时候已过去 2017目标营收千亿(确实有些新意)
    真正的转变从不确定中来
    很多人知道自己的斤两,他之所以抱怨工资低,不是觉得薪水和自己的能力不匹配,而是因为工资确实不够用(笑死了)
    CodeSmith
    sb2-admin
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10590811.html
Copyright © 2020-2023  润新知