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;
    }
  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4420861.html
Copyright © 2011-2022 走看看