UVA 11600 - Masud Rana(状态压缩DP+记忆化搜索)

E

Masud Rana

Input: Standard Input

Output: Standard Output

 

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.

 

2

3 1

2 3

4 1

2 3

 

Case 1: 1.0

Case 2: 3.5

 



题意:n个城市,城市间两两有一条道路,m条道路是没有怪物的,每天随机选一个城市,走过去,消灭途中的怪物,如果消灭完后,所有城市都可以不通过有怪物的道路到达就结束,问平均需要的天数。

思路:先把处理把已经可以相互到达的城市作为一个点,状态表示dp[u][s],当期在u这点,已经可以互相到达的城市集合为s,状态转移的方式为。

dp[u][s]时候,已经完成的城市数为have,还没完成的为n - have。那么要选中一个未完成的城市的概率为(n - have) / (n  - 1)。也就是平均需要(n - 1) / (n - have)次才能走到未完成的城市,然后在加上s|(1<<i)之后状态需要的平均时间*概率,概率为p[i] * (n - have)。所以状态转移方程为dp[u][s] = (n - 1) / ( n - have) + sum{dp[u][s|(1<<i)] * (p[i] * (n - have))}。

代码:

#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
using namespace std;

const int N = 35;
int t, n, m, p[N], pn, vis[N];
vector<int> g[N];
map<int, double> dp[N];

int bitcount(int x) {
	if (x == 0) return 0;
	else return bitcount(x/2) + (x&1);
}

int dfs(int u) {
	vis[u] = 1;
	int ans = 1;
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (vis[v]) continue;
		ans += dfs(v);
	}
	return ans;
}

double DP(int u, int s) {
	if (dp[u].count(s)) return dp[u][s];
	int have = 0, i;
	for (i = 0; i < pn; i++) {
		if (s&(1<<i))
			have += p[i];
	}
	if (have == n) return dp[u][s] = 0;
	dp[u][s] = (n - 1) * 1.0 / (n - have);
	for (i = 0; i < pn; i++) {
		if (s&(1<<i)) continue;
		dp[u][s] += DP(i, s|(1<<i)) * p[i] / (n - have);
	}
	return dp[u][s];
}

int main() {
	int cas = 0;
	scanf("%d", &t);
	while (t--) {
		pn = 0;
		memset(vis, 0, sizeof(vis));
		memset(g, 0, sizeof(g));
		scanf("%d%d", &n, &m);
		int u, v;
		while (m--) {
			scanf("%d%d", &u, &v);
			g[u].push_back(v);
			g[v].push_back(u);
		}
		for (int i = 1; i <= n; i++) {
			if (vis[i]) continue;
			dp[pn].clear();
			p[pn++] = dfs(i);
		}
		printf("Case %d: %.6lf\n", ++cas, DP(0, 1));
	}
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值