【BZOJ2595】【WC2008】游览计划

12人阅读 评论(0) 收藏 举报
分类:

【题目链接】

【思路要点】

  • 可以直接用基于连通性的的动态规划求解,或者可以用斯坦纳树DP+SPFA求解。
  • 时间复杂度\(O(N*M*3^K)\)。

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN	15
#define MAXQ	2000005
#define CURR	1024
#define INF	1e9
struct pos {int x, y, curr; };
int ans[MAXN][MAXN][CURR];
pos path[MAXN][MAXN][CURR];
int n, m, k, value[MAXN][MAXN], num[MAXN][MAXN];
bool inq[MAXN][MAXN][CURR], mark[MAXN][MAXN];
void work(pos home) {
	mark[home.x][home.y] = true;
	if (path[home.x][home.y][home.curr].curr == 0) return;
	pos tmp = path[home.x][home.y][home.curr];
	if (home.curr == tmp.curr) work(tmp);
	else work(tmp), work((pos) {tmp.x, tmp.y, home.curr ^ tmp.curr});
}
void update(int pi, int pj, int pc, int ti, int tj, int tc, int delta) {
	int tmp = ans[ti][tj][tc] + delta;
	if (tmp < ans[pi][pj][pc]) {
		ans[pi][pj][pc] = tmp;
		path[pi][pj][pc] = (pos) {ti, tj, tc};
	}
}
void push(pos a) {
	inq[a.x][a.y][a.curr] = true;
}
void pop(pos a) {
	inq[a.x][a.y][a.curr] = false;
}
bool query(pos a) {
	return inq[a.x][a.y][a.curr];
}
int main() {
	cin >> n >> m; k = 0;
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++) {
		cin >> value[i][j];
		if (value[i][j] == 0) num[i][j] = k++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++)
	for (int curr = 1; curr < 1 << k; curr++)
		if (value[i][j] == 0 && curr == 1 << num[i][j]) ans[i][j][curr] = 0;
		else ans[i][j][curr] = INF;
	for (int curr = 1; curr < 1 << k; curr++) {
		static pos q[MAXQ];
		int l = 0, r = -1;
		for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			for (int l = (curr - 1) & curr; l; l = (l - 1) & curr)
				update(i, j, curr, i, j, l, ans[i][j][curr ^ l] - value[i][j]);
			if (ans[i][j][curr] < INF) {
				q[++r] = (pos) {i, j, curr};
				push(q[r]);
			}
		}
		while (l <= r) {
			pos tmp = q[l++];
			pop(tmp);
			if (ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x][tmp.y + 1] < ans[tmp.x][tmp.y + 1][tmp.curr]) {
				ans[tmp.x][tmp.y + 1][tmp.curr] = ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x][tmp.y + 1];
				path[tmp.x][tmp.y + 1][tmp.curr] = tmp;
				if (!query((pos) {tmp.x, tmp.y + 1, tmp.curr})) {
					q[++r] = (pos) {tmp.x, tmp.y + 1, tmp.curr};
					push(q[r]);
				}
			}
			if (ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x][tmp.y - 1] < ans[tmp.x][tmp.y - 1][tmp.curr]) {
				ans[tmp.x][tmp.y - 1][tmp.curr] = ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x][tmp.y - 1];
				path[tmp.x][tmp.y - 1][tmp.curr] = tmp;
				if (!query((pos) {tmp.x, tmp.y - 1, tmp.curr})) {
					q[++r] = (pos) {tmp.x, tmp.y - 1, tmp.curr};
					push(q[r]);
				}
			}
			if (ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x + 1][tmp.y] < ans[tmp.x + 1][tmp.y][tmp.curr]) {
				ans[tmp.x + 1][tmp.y][tmp.curr] = ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x + 1][tmp.y];
				path[tmp.x + 1][tmp.y][tmp.curr] = tmp;
				if (!query((pos) {tmp.x + 1, tmp.y, tmp.curr})) {
					q[++r] = (pos) {tmp.x + 1, tmp.y, tmp.curr};
					push(q[r]);
				}
			}
			if (ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x - 1][tmp.y] < ans[tmp.x - 1][tmp.y][tmp.curr]) {
				ans[tmp.x - 1][tmp.y][tmp.curr] = ans[tmp.x][tmp.y][tmp.curr] + value[tmp.x - 1][tmp.y];
				path[tmp.x - 1][tmp.y][tmp.curr] = tmp;
				if (!query((pos) {tmp.x - 1, tmp.y, tmp.curr})) {
					q[++r] = (pos) {tmp.x - 1, tmp.y, tmp.curr};
					push(q[r]);
				}
			}
		}
	}
	int finalans = INF, goal = (1 << k) - 1;
	pos home;
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++)
		if (ans[i][j][goal] < finalans) {
			finalans = ans[i][j][goal];
			home = (pos) {i, j, goal};
		}
	cout << finalans << endl;
	work(home);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++)
			if (mark[i][j]) {
				if (value[i][j]) cout << 'o';
				else cout << 'x';
			} else cout << '_';
		cout << endl;
	}
	return 0;
}

查看评论

大数据40天精英计划

离线数据分析平台是一种利用hadoop集群开发工具的一种方式,主要作用是帮助公司对网站的应用有一个比较好的了解。 尤其是在电商、旅游、银行、证券、游戏等领域有非常广泛,因为这些领域对数据和用户的特性把握要求比较高,所以对于离线数据的分析就有比较高的要求了。 是一切大数据的基础。
  • 2017年06月07日 11:46

【BZOJ2595】 [Wc2008]游览计划

斯坦纳树~ 用spfa转移动态规划~~
  • Regina8023
  • Regina8023
  • 2015-01-10 17:26:02
  • 1394

[bzoj2595][WC2008]游览计划

2595: [Wc2008]游览计划Time Limit: 10 Sec Memory Limit: 256 MBSec Special Judge Submit: 849 Solved: 3...
  • FZHvampire
  • FZHvampire
  • 2015-08-25 08:15:48
  • 1245

bzoj 2595: [Wc2008]游览计划(斯坦纳树)

2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special Judge Submit: 1253  Solved: ...
  • clover_hxy
  • clover_hxy
  • 2016-05-28 07:57:26
  • 396

WC2008观光游览【BZOJ2595】【斯坦纳树】

WC2008观光游览【BZOJ2595】【斯坦纳树】神奇的解法题目传送点想了解斯坦纳树的戳这其实这种表格的题目还可以写插头DP(•‾̑⌣‾̑•)✧˖° (不会= =|||) 我们忽略刚刚的话题,说...
  • s2364079
  • s2364079
  • 2016-01-20 21:43:40
  • 986

bzoj2595: [Wc2008]游览计划

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2595 思路:斯坦纳树 斯坦纳树问题就是给你n个点的图,点或边上有权值,有k个点是关键点 求使...
  • thy_asdf
  • thy_asdf
  • 2016-05-08 19:47:25
  • 369

【bzoj2595】[Wc2008]游览计划 斯坦纳树

学一下这个模型,以前一直以为是到插头dp,实质上只是个状压dp f[i][j][S]表示现在在点(i,j),与(i,j)联通的点的集合为S的最小值 f[i][j][S]=min{f[i][j][s...
  • u012288458
  • u012288458
  • 2016-06-23 09:58:00
  • 339

【WC2008】bzoj2595 游览计划

斯坦纳树
  • sdfzyhx
  • sdfzyhx
  • 2017-01-20 19:28:48
  • 113

bzoj2595 游览计划 斯坦纳树&状压Dp

一直不知道斯坦纳树是什么东西。。。(搞得我现在完全知道了一样)。大概就是求一棵树连接一些带权点使某个总和最小吧。(就是一个理论模型而已不是什么算法?)        所以这道题目求得是一个斯坦纳树很...
  • lych_cys
  • lych_cys
  • 2016-03-08 09:53:57
  • 790

Bzoj2595: [Wc2008]游览计划

原题网址:http://www.lydsy.com/JudgeOnline/problem.php?id=2595标算是斯坦纳树,其实类似状压dp。 首先答案一定是树形的,否则断开一条环上边,不影响...
  • MintGreenTZ
  • MintGreenTZ
  • 2016-09-13 11:17:14
  • 158
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 3046
    排名: 1万+
    文章分类
    文章存档