zoukankan      html  css  js  c++  java
  • BZOJ1417: Pku3156 Interconnect

    1417: Pku3156 Interconnect

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 271  Solved: 136
    [Submit][Status][Discuss]

    Description

    给出无向图G(V, E). 每次操作任意加一条非自环的边(u, v), 每条边的选择是等概率的. 问使得G连通的期望操作次数. (|V| <= 30, |E| <= 1000)

    Input

    第一行两个整数N,M 1<=N<=30 0<=M<=1000 接下来M行,每行两个整数X,Y表示两者之间已修好一条道路. 两点之间可以不止修了一条路,也有可能M条路已使N个点成为一个整体.

    Output

    输出一个小数,表示新修道路条数的期望值,保留六位小数.

    Sample Input

    4 2
    1 2
    3 4

    Sample Output

    1.500000

    HINT

     

    Source

    题解:我们考虑已存在边对建边是没有影响的,但是对于使图联通是有影响的,所以我们就可以利用这一点进行状态转移

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #include<vector>
    #define ll long long 
    #define vec vector<int>
    using namespace std;
    map <vec ,double> q;
    vec ve;
    int fa[35],size[35],all;
    int n,m;
    int read()
    {
        int x=0,f=1; char ch;
        while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') f=-1;
        while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
        return x*f;
    }
    int find(int x)
    {
        if (fa[x]!=x) fa[x]=find(fa[x]); return fa[x];
    }
    void init()
    {
        n=read(); m=read();
        for (int i=1; i<=n; i++) fa[i]=i,size[i]=1;
        for (int i=1; i<=m; i++)
        {
            int u=read(),v=read();
            int q=find(u),p=find(v);
            if (q!=p) fa[q]=p,size[p]+=size[q];
        }
        for (int i=1; i<=n; i++) if (fa[i]==i) ve.push_back(size[i]);
        sort(ve.begin(),ve.end());
        all=n*(n-1)/2;
    }
    double solve(vec ve)
    {
        if (q.count(ve)) return q[ve];
        if (ve.size()==1) return q[ve]=0;
        int sz=ve.size(); int p=0;
        for (int i=0; i<sz; i++) p+=ve[i]*(ve[i]-1)/2;
        double ans=1.0*all/(all-p); 
        for (int i=0; i<sz; i++)
        {
            for (int j=0; j<i; j++)
            {
                vec v=ve;
                v[j]+=v[i]; swap(v[i],v[sz-1]);
                v.pop_back(); sort(v.begin(),v.end());
                ans+=1.0*ve[i]*ve[j]/(all-p)*solve(v);
            }
        }
        return q[ve]=ans;
    }
    int main()
    {
        init();
        printf("%0.6lf
    ",solve(ve));
    }
    View Code
  • 相关阅读:
    Java之修改文件内容:字符串逐行替换
    Java之"instanceof"和"isInstance"代码举例
    spring之跨模块引用配置文件
    Java之相对路径找不到文件问题解决方法
    html 页面模块的常用命名
    移动端资源集锦
    手机web不同屏幕字体大小高度自适应
    meta标签整理
    css文字超出自动显示省略号
    display:inline、block、inline-block的区别
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5793779.html
Copyright © 2011-2022 走看看