UVA 11600 Masud Rana 并查集+状压概率dp

题目链接:点击打开链接

题意:给定一个无向图,给定的边是已经存在的边,每天会任选两个点新建一条边(建过的边还会重建)

问:使得图连通的天数的期望。

思路:状压喽,看别人都是这么写的,n=30,m=0 我也不知道怎么办了。。

当前连通块点数为X 加入一个Y个点的连通块需要的天数为 Y/(n-X);

Masud Rana, A Daring Spy Of Bangladesh Counter Intelligence. He is in a new mission. There is a

total n cities in Bangladesh. Each city is connected to all other by bidirectional roads. So there are

total n ? (n ? 1)/2 bidirectional roads. Many of the roads are under control of evil powers. City a is

safely reachable from city b, if there is a path from a to b containing only roads which are not under

control of evil powers. There are m roads which are safe from evil powers. The mission of Masud Rana

is to destroy the evil powers of some roads, and make sure that every city is safely reachable from all

other.

Masud Rana chose a new strategy for this special mission. Every morning he selects a random city

other than the city he stays in at that moment, and visit that city by direct connecting road, in the

time of his visit by the road he destroys all evil power of that road if exists any, and makes that road

safe. After reaching new city, he stays there till next morning. In the next morning he checks whether

all cities are safely reachable from all others. If he is already done his mission ends, otherwise he repeats

same strategy.

Let us number the cities by 1, 2, . . . , n. Masud Rana is in city 1 when he starts his mission.

What is the expected number of days to finish the mission for Masud Rana.

Input

Input will starts with an integer T (T ≤ 100) which denotes the number of test case. Each case starts

with two integer N (N ≤ 1 ≤ 30) and M (0 ≤ M ≤ N ? (N ? 1)/2). Each of the next lines contains

two integers a and b (1 ≤ a, b ≤ N) which means road connecting city a and b is safe.

Output

You have to output the expected number of days required for Masud Rana. Print the case number

followed by the output. Look at the sample in/out for exact format. Upto 1E-6 error in your output

will be acceptable.

Sample Input

2

3 1

2 3

4 1

2 3

Sample Output

Case 1: 1.0

Case 2: 3.5

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <map>
#include <vector>
using namespace std;
#define N 35
#define M 35*35
#define inf 10000000
struct Edge{
	int from, to, next;
	bool cut;
}edge[2 * M];
int head[N], edgenum;
int n, m;
void add(int u, int v){
	Edge E = { u, v, head[u], 0 }; edge[edgenum] = E; head[u] = edgenum++;
	Edge E2 = { v, u, head[v], 0 }; edge[edgenum] = E2; head[v] = edgenum++;
}

int f[N], siz[N];
int find(int x){ return x == f[x] ? x : f[x] = find(f[x]); }
bool Union(int x, int y){
	int fx = find(x), fy = find(y);
	if (fx == fy)return false;
	if (fx < fy)swap(fx, fy);
	f[fx] = fy;
	siz[fy] += siz[fx];
	return true;
}
vector<int>A;
void suodian(){
	for (int i = 1; i <= n; i++)f[i] = i, siz[i] = 1;
	for (int i = 0; i < edgenum; i += 2){
		int u = edge[i].from, v = edge[i].to;
		Union(u, v);
	}
	for (int i = 1; i <= n; i++)find(i);
	A.clear();
	for (int i = 1; i <= n; i++)if (f[i] == i)
		A.push_back(siz[i]);
}
void init(){ edgenum = 0; memset(head, -1, sizeof(head)); }

map<int, double> dp;
int cnt(int x){
	int ans = 0;
	for (int i = 0; i < A.size(); i++)
		if ((1 << i) & x)
			ans += A[i];
	return ans;
}
double dfs(int x){
	if (dp.count(x))return dp[x];
	int num = cnt(x);
	if (num == n)return dp[x] = 0;
	double ans = (double) (n-1)/(n-num);
	for (int i = 0; i < A.size(); i++){
		if (0 == ((1 << i) & x)){
			ans += dfs((1 << i) ^ x) * A[i] / (n-num);
		}
	}
	return dp[x] = ans;
}
void input(){
	init();
	scanf("%d %d", &n, &m);
	while (m--){
		int u, v; scanf("%d %d", &u, &v);
		add(u, v);
	}
}
int main(){
	int T, Cas = 1; scanf("%d", &T);
	while (T--){
		input();
		suodian();
		dp.clear();
		printf("Case %d: %.10f\n", Cas++, dfs(1));
	}
	return 0;
}
时间: 2024-10-11 20:47:13

UVA 11600 Masud Rana 并查集+状压概率dp的相关文章

HDU 4336 Card Collector(状压 + 概率DP 期望)题解

题意:每包干脆面可能开出卡或者什么都没有,一共n种卡,每种卡每包爆率pi,问收齐n种卡的期望 思路:期望求解公式为:$E(x) = \sum_{i=1}^{k}pi * xi + (1 - \sum_{i = 1}^{k}pi) * [1 + E(x)]$,即能转换到x情况的期望+x情况原地踏步的期望. 因为n比较小,我们可以直接状压来表示dp[x]为x状态时集齐的期望.那么显然dp[111111111] = 0.然后我们状态反向求解.最终答案为dp[0]. 然后来看期望的求解:$E(x) =

codeforces 482c 状压+概率DP

题意:给出N个不同的串,长度一样,别人随机选一个串,你要询问他那个串某一个位置是什么字符直到能确定那个串才能停止,问询问次数的期望. 题解:50个串20个位置容易想到状压,把字符串长度状压先考虑能否在某一个状态确定哪些字符串能确定哪些不能确定,需要2^m*m次,然后时间上不能再乘以n不然会爆,想想只要我知道到达某一个猜位置状态的概率dp[i],再知道相对应有哪些字符串可以确定和不可以确定,用f[i]来表示,那么对于不能确定的字符串相当于就要再猜一步,那么加上这个状态的概率就行了,不会再需要乘以n

HDU-4336 Card Collector(状压概率DP||容斥原理)

Card Collector http://acm.hdu.edu.cn/showproblem.php?pid=4336 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Special Judge Problem Description In your childhood, do you crazy for collecting the beautiful cards in

UVA 11600 Masud Rana(概率dp)

当两个城市之间有安全的道路的时候,他们是互相可到达的,这种关系满足自反.对称和传递性, 因此是一个等价关系,在图论中就对应一个连通块. 在一个连通块中,当前点是那个并不影响往其他连通块的点连边,因此只要记录当前连通块内有哪些点. n<=30,数组是开不下的,而且状态转移是很少的,只会向二进制1数量增加的方向转移,所以用map保存.(最极限的应该是是2^29...) 适合用记忆化搜索来写. 很容易想到的转移方程是 S表示当前所在连通块,p是向连通快内点走的概率,trans走向某个点的概率,newS

HDU 4336 Card Collector 状压+概率dp

题目链接:点击打开链接 题意: 有n种卡片,每吃一包方便面都有一定概率获得其中一种卡片(也可能不获得卡片) 问集齐n张召唤神龙需要吃的方便面包数的期望. 思路: dp[i] 表示已经拥有卡片的状态为i, 还需要吃多少包才能拥有所有卡片, 显然 dp[(1<<n)-1] = 0; (已经拥有卡片就不用吃了嘛) 而答案就是dp[0]; 用样例二举例,下面dp方程内直接用二进制表示,为了方便观察,我们用最高位表示第一张卡片(P1=0.1),最低位表示第n张卡片(P2=0.4) dp[01]  = (

UVA 10158 War(并查集)

War A war is being lead between two countries, A and B. As a loyal citizen of C, you decide to help your country's espionage by attending the peace-talks taking place these days (incognito, of course). There are n people at the talks (not including y

SPOJ BALNUM Balanced Numbers 状压+数位DP

一开始想了一个用二进制状压的方法,发现空间需要的太大,光光memset都要超时 = = 其实不用每次都memset 也可以用三进制,一开始直接打表出所有的状态转移就好 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream&g

uva 10608 Friends(并查集)

uva 10608 Friends 题目大意:给出两两之间的关系,求出最大的关系网. 解题思路:并查集裸体. #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> using namespace std; const int N = 30005; typedef long long ll; int n, m; in

uva 12232 - Exclusive-OR(加权并查集)

题目链接:uva 12232 - Exclusive-OR 题目大意:有n个数,一开始并不知道具体的值,现在进行Q次操作. I u k:au的值为k I u v k:au?av=k Q k q1q2-qk:求q1?q2-?qk 对于Q操作不能确定的话输出"I don't know." 对于I操作矛盾的话则输出是第几条I操作出现矛盾的,并且停止后面所有的操作. 解题思路:加权并查集,f[x]表示x节点父亲节点,d[x]表示x节点与其父节点的亦或值,对于确定的节点值,可以将父亲节点设为0,