zoukankan      html  css  js  c++  java
  • UVa 11600

    有一个n个点m条边的无向图,你初始在1号点,每次移动你会等概率随机选择除了你所在的点之外的某个点,如果这两个点之间还没有边则连一条边,求使整个图联通的期望步数。

    $$1 leq n leq 30,0 leq m leq frac{n(n-1)}{2}$$

    先缩点,然后设$f(S)$为当前联通块中的点为$S$这个集合时使图联通的期望步数,$ ext{cnt}_S$为$S$中点数,$ ext{belong}_i$为$i$所属联通块,则有

    $$f(S)=frac{n-1}{n- ext{cnt}_S} + sum_{i otin S} frac{1}{n- ext{cnt}_S} f(S cup ext{belong}_i)$$

    前面的式子由几何级数推出,边界是$f(V)=0$,用哈希表存状态,记搜就可以过了。(但这样过不了极限数据,比较迷。。。)

    const int MAXN = 30 + 5;
    
    struct DSU {
      int fa[MAXN];
      
      void init(int n) {
        For(i, 1, n)
          fa[i] = i;
      }
      
      int find(int x) {
        return fa[x] == x ? x : fa[x] = find(fa[x]);
      }
      
      bool same(int x, int y) {
        return find(x) == find(y);
      }
      
      void merge(int x, int y) {
        if (!same(x, y))
          fa[fa[y]] = fa[x];
      }
    } U;
    
    int bel[MAXN], linker[MAXN], n, m;
    
    std::unordered_map < int, double > f;
    
    double DP(int S) {
      int cnt = __builtin_popcount(S);
      if (cnt >= n)
        return 0;
      auto it = f.find(S);
      if (it != f.end())
        return it->S;
      double res = 1.0 * (n - 1) / (n - cnt);
      For(i, 1, n)
        if (!(S & (1 << i)))
          res += 1.0 * 1 / (n - cnt) * DP(S | linker[bel[i]]);
      return f[S] = res;
    }
    
    int main() {
      int _;
      scanf("%d", &_);
      For(i, 1, _) {
        memset(linker, 0, sizeof linker);
        scanf("%d%d", &n, &m);
        U.init(n);
        f.clear();
        For(i, 1, m) {
          int u, v;
          scanf("%d%d", &u, &v);
          U.merge(u, v);
        }
        For(i, 1, n)
          linker[bel[i] = U.find(i)] += 1 << i;
        printf("Case %d: %.10f
    ", i, DP(linker[bel[1]]));
      }
      return 0;
    }
  • 相关阅读:
    前端杂七杂八
    用户数据分析
    hash表
    django杂七杂八
    redis事务
    CF1457D XOR-gun
    后缀数组学习笔记
    CF1439C Greedy Shopping
    P3320 [SDOI2015]寻宝游戏
    P5327 [ZJOI2019]语言
  • 原文地址:https://www.cnblogs.com/sjkmost/p/9778762.html
Copyright © 2011-2022 走看看