Interconnect - POJ 3156 期望+状压dp
来源:互联网 发布:wampserver域名重定向 编辑:程序博客网 时间:2024/04/28 08:18
Description
There are two serious problems in the Kingdom of Lipshire: the roads and the fools who build them. Once upon a time, the King of Lipshire has decided to improve the road system because some roads became completely impassable — it was easier to travel cross-country instead of using those roads.
By King’s decree, new roads are to be built in Lipshire. Of course, the new road system must interconnect all towns, i. e. there must be a path connecting any two towns of Lipshire.
The road administration of Lipshire has resources to build exactly one road per year. Unfortunately, the fools who build these roads are completely out of control. So, regardless of the orders given, the fools randomly select two different towns a and b and build a road between them, even when those towns are already connected by a road. All possible choices are equiprobable. The road is build in such a manner that the only points where a traveler can leave it are the towns connected by this road. The only good thing is that all roads are bidirectional.
The King knows about the problem, but he cannot do anything about it. The only thing King needs to know is the expected number of years to wait before the road system of Lipshire becomes interconnected. He asked you to provide this information.
Input
The first line of the input contains two integers n and m (2 ≤ n ≤ 30, 0 ≤ m ≤ 1 000) — the number of towns in Lipshire, and the number of roads which are still good. The following m lines describe roads, one per line. Each road is described with two endpoints — two integer numbers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi). There can be multiple roads between two towns, but the road from a town to itself is not allowed.
Output
Output the expected number of years to wait for the interconnected road system. If the system is already interconnected, output zero as an answer. Output the number with at least six precise digits after the decimal point.
Sample Input
sample input #12 11 2sample input #24 21 23 4
Sample Output
sample output #10.0sample output #21.5
题意:给你一些点和边,每次随机让其中两个点相连,问你使得所有的点连通,增加的边的期望是多少。
思路:num[i]表示恰好有i个点连通的区域有多少个,S状压这种情况,S2表示让其中某些区域相连后的状压情况dp[S]=(k1*dp[S2_1]+k2*dp[S2_2]...+k3*dp[S])/[n*(n-1)/2]+1.这是基本的转移方程,n*(n-1)/2为一共有多少种连接方式,k表示达到S2的有几种连接方式。
另外我的代码在vj上交了之后跑出了141ms,目前直接上了第一的位置,【虽然拿自己的号只跑出了157ms
AC代码如下:
#include<cstdio>#include<cstring>#include<map>using namespace std;typedef unsigned long long ll;struct node{ int num[35]; double p;}box[10010];map<ll,int> match;int n,n2,m,p[40],sum[40],num;ll Hash[40],MOD=1e9+7;int find(int x){ return p[x]==x ? p[x] : p[x]=find(p[x]);}void Union(int u,int v){ u=find(u); v=find(v); if(u!=v) { p[u]=v; sum[v]+=sum[u]; }}void debug(int pos){ for(int i=1;i<=5;i++) printf("%d ",box[pos].num[i]); printf("\n");}double solve(ll S){ int pos=match[S],i,j,k,temp=0; ll S2; double ret=0; if(box[pos].num[0]==1) return box[pos].p; box[pos].num[0]=1; if(S==Hash[n]) { box[pos].p=0; return 0; } for(i=1;i<=n;i++) if(box[pos].num[i]>0) for(j=i+1;j<=n;j++) if(box[pos].num[j]>0) { S2=S-Hash[i]-Hash[j]+Hash[i+j]; if(match[S2]==0) { num++; match[S2]=num; for(k=1;k<=n;k++) box[num].num[k]=box[pos].num[k]; box[num].num[i]--; box[num].num[j]--; box[num].num[i+j]++; } k=box[pos].num[i]*i*box[pos].num[j]*j; ret+=k*solve(S2); temp+=k; } for(i=1;i<=n;i++) if(box[pos].num[i]>=2) { S2=S-2*Hash[i]+Hash[i*2]; if(match[S2]==0) { num++; match[S2]=num; for(k=1;k<=n;k++) box[num].num[k]=box[pos].num[k]; box[num].num[i]-=2; box[num].num[i*2]++; } j=box[pos].num[i]*i; k=j*(j-1)/2-i*(i-1)/2*box[pos].num[i]; ret+=k*solve(S2); temp+=k; } box[pos].p=(ret+n2)/temp; return box[pos].p;}int main(){ int i,j,k,u,v; ll S; Hash[0]=1; for(i=1;i<=30;i++) Hash[i]=Hash[i-1]*MOD; scanf("%d%d",&n,&m); n2=n*(n-1)/2; for(i=1;i<=n;i++) { p[i]=i; sum[i]=1; } for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); Union(u,v); } for(i=1;i<=n;i++) if(p[i]==i) box[1].num[sum[i]]++; S=0; for(i=1;i<=n;i++) S+=(ll)box[1].num[i]*Hash[i]; match[S]=1;num=1; printf("%.6f\n",solve(S));}
- Interconnect - POJ 3156 期望+状压dp
- POJ 3156 Interconnect(期望DP)
- POJ 3156 Interconnect 并查集+期望dp
- [期望DP] BZOJ 1417 Pku3156 Interconnect
- BZOJ 1417: Pku3156 Interconnect 期望DP
- BZOJ 1417: Pku3156 Interconnect (期望DP)
- POJ 3156 Interconnect
- POJ 3156 Interconnect 笔记
- POJ 3156 HASH 期望DP
- POJ 2096 期望DP
- POJ 2096 期望dp
- poj 2096(dp数学期望)
- Poj 2096 (dp求期望)
- poj 2096 dp 求 期望
- poj 2096(期望dp)
- poj 3682(期望dp)
- Poj 2096 (dp求期望) 概率dp
- uva 1390 - Interconnect(期望+哈希+记忆化)
- LeetCode OJ 之 Insert Interval (插入区间)
- pat1023
- vs 提示图标的含义
- 《MonkeyRunner原理剖析》第九章-MonkeyImage实现原理 - 第五节 - 图片处理基类ChimpImageBase
- 我的python学习笔记2
- Interconnect - POJ 3156 期望+状压dp
- 云计算设计模式翻译(五):Compute Resource Consolidation Pattern
- java并发编程-限时任务
- POJ1511 Invitation Cards【SPFA】
- 《MonkeyRunner原理剖析》第九章-MonkeyImage实现原理 - 第六节 - 截屏图片处理类AdbChimpImage
- Dell 1628S WIN8.1 安装Ubuntu 14.04教程
- 理解Shared Pool 1
- 关键字volatile的含意
- poj 1026