zoukankan      html  css  js  c++  java
  • BZOJ 3925: [Zjoi2015]地震后的幻想乡(概率)

    CLJ就是喜欢出ctsc上讲的东西,看来还是得找时间把他的那几道题做下

    首先记f(x)为答案>x的概率,那么把这个东西从0到1积分就是答案了

    f(x)<=>边小于x不能使图联通的概率

    这个有点难求,考虑求使图联通的概率

     记f(s)为集合s联通的概率,那么f(s)=1-sigma(f(s')*(1-x)^cnt) (s'属于s且s'一定包含某点k,cnt为链接s'与Cs s'的边数)

    可以发现f(s)是个多项式,就可以积分了

    由于还没用上64位评测系统,double还是不能过,只好用__float128,比较慢而已

    CODE:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef vector<__float128> ploy;
    ploy operator + (ploy x,ploy y){
        ploy ans(max(x.size(),y.size()),0);
        for (int i=0;i<ans.size();i++) {
            if (i<x.size()) ans[i]+=x[i];
            if (i<y.size()) ans[i]+=y[i];
        }
        return ans;
    }
    ploy operator - (ploy x,ploy y) {
        ploy ans(max(x.size(),y.size()),0);
        for (int i=0;i<ans.size();i++) {
            if (i<x.size()) ans[i]+=x[i];
            if (i<y.size()) ans[i]-=y[i];
        }
        return ans;
    }
    ploy operator * (ploy x,ploy y) {
        ploy ans(x.size()+y.size()-1,0);
        for (int i=0;i<x.size();i++) 
            for (int j=0;j<y.size();j++) 
                ans[i+j]+=x[i]*y[j];
        return ans;
    }
    bool b[1040];
    ploy f[1040],quick[100];
    int n,m;
    struct edges{int x,y;}e[100];
    ploy ONE(1,1);
    inline void print(ploy x){
        printf("%d
    ",x.size());
        for (int i=0;i<x.size();i++) printf("%lf ",double(x[i]));
        printf("
    ");
    }
    void dp(int x){
        if (b[x]) return ;
        b[x]=1;
        ploy tmp(0,0);
        for (int i=1;i<(1<<n);i++) {
            if (!(i&1)) continue;
            if ((i&x)!=i) continue;
            if (i==x) continue;
            int j=x^i;
            int cnt=0;
            for (int k=1;k<=m*2;k++) 
                if (i&(1<<e[k].x)&&j&(1<<e[k].y)) cnt++;
            dp(i);
            tmp=tmp+f[i]*quick[cnt];
        }
        f[x]=ONE-tmp;
    }
    __float128 cal(ploy x) {
        __float128 ans=0;
        for (int i=0;i<x.size();i++) ans+=x[i]*1.0/(i+1);
        return ans;
    }
    int main()    {
        scanf("%d%d",&n,&m);
        quick[0]=ONE;
        quick[1]=ploy(2,0);
        quick[1][0]=1;quick[1][1]=-1;
        for (int i=2;i<=m;i++) quick[i]=quick[i-1]*quick[1];
        for (int i=1;i<=m;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            x--,y--;
            e[i*2-1]=(edges){x,y};
            e[i*2]=(edges){y,x};
        }
        b[1]=1;f[1]=ONE;
        dp((1<<n)-1);
        ploy ans=ONE-f[(1<<n)-1];
        printf("%.6lf
    ",double(cal(ans)));
        return 0;
    }
  • 相关阅读:
    1434. Buses in Vasyuki 夜
    SAP
    目标
    组合数
    KM算法模板
    网络流
    CodeForces 43E
    B. Unsorting Array codeforces 127
    Colorful Rainbows 127
    C. Anagram codeforces
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4420861.html
Copyright © 2011-2022 走看看