POJ 3156 - Interconnect (概率DP+hash)
题意:给一个图,有些点之间已经连边,现在给每对点之间加边的概率是相同的,问使得整个图连通,加边条数的期望是多少。
此题可以用概率DP+并查集+hash来做。
用dp(i,j,k...)表示当前的每个联通分量的点数分别是i,j,k...(连通分量的个数不固定)时,加边的期望。
这样以dp(i,j,k)为例分析状态转移的过程,dp(i,j,k)=p1*dp(i,j,k)+p2*dp(i+j,k)+p3*dp(i,j+k)+p4*dp(j,i+k)+1。
终止条件是dp(n)=0,因为此时图一定联通,所以期望是0。
这个式子是怎么来的呢?
p1*dp(i,j,k)表示增加了一条边之后原来的联通分量没有改变时的情况,p1表示选中这样的无用边的概率;p2*dp(i+j,k)表示增加了一条连结i和j这两个联通分量的边,p2表示选中i和j之间的边的概率。最后的1表示增加了一条边。
这里我们要计算选边概率。
首先有n*(n-1)/2条边。
如果选中了不改变图的联通分量的边,此时说明每次加的边都属于一个连通分量,所以一共有sum{(cnt(i)*cnt(i)-1)/2}(cnt(i)表示该联通分量内有cnt(i)个点)种选择情况。
如果选中了某条边连结了某两个联通分量i、j,这个时候一共有cnt(i)*cnt(j)种情况。
计算概率只需要除以边的总数即可。
计算连通分量可以用并查集。
因为这个题只看图的连通情况不在乎具体是哪个点,因此可以对每个联通分量的点数排序,使得每个状态唯一,这样可以得到很多重叠的子问题,整个问题就可以用记忆化搜索完成了。
很明显问题的状态比较复杂,直接下手很难处理也容易超时,所以用hash处理状态压缩判重。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#define MOD 100007
using namespace std;
int n,m;
struct State
{
double val;
];
bool vis;
State()
{
memset(x,,sizeof(x));
vis=false;
}
void clear()
{
memset(x,,sizeof(x));
vis=false;
}
void mysort()
{
sort(x,x+);
}
int myhash() const
{
;
,b=; i>=&&x[i]; --i)
{
res+=x[i]*b;
res%=MOD;
b*=;
b%=MOD;
}
return res;
}
bool operator ==(State &t)const
{
; i<; ++i) if(x[i]!=t.x[i]) return false;
return true;
}
bool operator !=(State &t) const
{
return !(*this==t);
}
};
State has[MOD+],st;
void inserthash(State &p)
{
int v=p.myhash();
while(has[v].vis)
;
has[v]=p;
has[v].vis=true;
}
double gethash(State &p)
{
int v=p.myhash();
while(has[v].vis&&has[v]!=p)
;
;
}
];
int find(int p)
{
return p==father[p]?p:(father[p]=find(father[p]));
}
void init()
{
; i<=n; ++i) father[i]=i;
st.clear();
}
double DP(State &s)
{
;
double v=gethash(s);
if(v!=-1.0) return v;
,sn=n*(n-)/2.0;;
; i>=&&s.x[i]; --i)
q+=s.x[i]*(s.x[i]-)/2.0;
double &res=s.val;
res=;
; i>=&&s.x[i]; --i)
; j>=&&s.x[j]; --j)
{
double p=s.x[i]*s.x[j]/sn;
State t;
; k>=; --k)
if(k!=i&&k!=j) t.x[k]=s.x[k];
else if(k==i) t.x[k]=s.x[i]+s.x[j];
;
t.mysort();
res+=p*DP(t);
}
res=res/(-q/sn);
inserthash(s);
return res;
}
];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
; i<m; ++i)
{
int x,y;
scanf("%d%d",&x,&y);
int fx=find(x),fy=find(y);
if(fx!=fy) father[fx]=fy;
}
memset(cnt,,sizeof(cnt));
; i<=n; ++i)
cnt[find(i)]++;
; i<=n; ++i)
st.x[i-]=cnt[i];
st.mysort();
printf("%.6f\n",DP(st));
}
;
}
学习了http://www.cnblogs.com/swm8023/archive/2012/09/21/2696593.html。
POJ 3156 - Interconnect (概率DP+hash)的更多相关文章
- poj 1322 Chocolate (概率dp)
///有c种不同颜色的巧克力.一个个的取.当发现有同样的颜色的就吃掉.去了n个后.到最后还剩m个的概率 ///dp[i][j]表示取了i个还剩j个的概率 ///当m+n为奇时,概率为0 # inclu ...
- POJ 3071 Football(概率DP)
题目链接 不1Y都对不住看过那么多年的球.dp[i][j]表示i队进入第j轮的概率,此题用0-1<<n表示非常方便. #include <cstdio> #include &l ...
- Scout YYF I POJ - 3744(概率dp)
Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into th ...
- POJ - 2151 (概率dp)
题意:有T个队伍,有M道题,要求每个队至少有一道题,并且有队伍至少过N道题的概率. 这个题解主要讲一下,后面的,至少有一道题解决和至少一道题至N-1道题解决,到底怎么算的,其实,很简单,就是母函数. ...
- poj 3071 Football (概率DP水题)
G - Football Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit ...
- POJ 1202 Family 概率,DP,高精 难度:2
http://poj.org/problem?id=1202 难度集中在输出格式上,因为输出格式所以是高精度 递推式: 血缘肯定只有从双亲传到儿子的,所以,设f,m为双亲,son为儿子,p[i][j] ...
- poj 3071 Football(概率dp)
id=3071">http://poj.org/problem? id=3071 大致题意:有2^n个足球队分成n组打比赛.给出一个矩阵a[][],a[i][j]表示i队赢得j队的概率 ...
- 【POJ】2151:Check the difficulty of problems【概率DP】
Check the difficulty of problems Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8903 ...
- POJ 2096 Collecting Bugs (概率DP,求期望)
Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...
随机推荐
- 解决PhoneGap不支持viewport的几种方法
前几天用phonegap编译GameBuilder+CanTK时,发现HTML里的viewport无效.CanTK根据devicePixelRatio检测设备的DPI,然后用viewport设置正确的 ...
- struts2后台返回json到jsp页面
1.在action定义一个全局变量如: private Map<String, Object> dataMap; 2.控制层方法 说明:主要的目的是把我们定义的Map转为Json对象,然后 ...
- hdu 4034 Graph (floyd的深入理解)
Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Submi ...
- iOS开发之——从零开始完成页面切换形变动画
前言 某天我接到了UI发给我的两张图: 需求图.png 看到图的时候我一脸懵逼,显然我需要做一个页面切换的指示动画.老实说,从大三暑假开始做iOS开发也一年有余了,但是遇到复杂动画总是唯恐避之不及,只 ...
- 使用DD_belatedPNG让IE6支持PNG透明图片
使用DD_belatedPNG让IE6支持PNG透明图片 众所周知IE6不支持透明的PNG图片,而PNG图片在Web设计方面表现力上,具有其它图形格式所达不到的效果,IE6这一致命缺陷极大地限制了We ...
- uva 1629
1629 - Cake slicing Time limit: 3.000 seconds A rectangular cake with a grid of m * n <tex2html_v ...
- BZOJ1570 [JSOI2008]Blue Mary的旅行
建分层图,每一层表示一天的情况 从S向第0层的1号点连边,每层的n向T连INF的边 枚举天数,每多一天就多建一层然后跑最大流,如果当前流量大于人数则输出答案 由于路径长度不会超过n,因此tot个人走这 ...
- Js笔试题之千分位格式化
用js实现如下功能,将给定的数字转化成千分位的格式,如把“10000”转化成“10,000”,并考虑到性能方面的因素. 一.首先想到的办法,将数字转换为字符串(toString())再打散成数组(sp ...
- S1:运算符
中括号和小括号的用法: 一般而言,对象中的属性的值是通过点(.)运算符来取值,但是考虑到这样一种情况,我们在遍历一个对象的时候,对其中的属性的键(key)是一无所知的,我们怎么通过点(.)来访问呢?这 ...
- swift 开眼今日精选
swift 开眼今日精选 import UIKit class TodayController: UITableViewController { vararray =NSMutableArray() ...