# [BZOJ2595][Wc2008]游览计划

[BZOJ2595][Wc2008]游览计划

z  ‘_’（下划线）表示该方块没有安排志愿者；
z  ‘o’（小写英文字母o）表示该方块安排了志愿者；
z  ‘x’（小写英文字母x）表示该方块是一个景点；

4 4
0 1 1 0
2 5 5 1
1 5 5 1
0 1 1 0

6

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <queue>
using namespace std;

int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}

#define maxn 11
#define maxs 1030
#define oo 2147483647

int n, m, K, A[maxn][maxn], f[maxn][maxn][maxs];

struct Sta {
int x, y, S;
Sta(): x(0), y(0), S(0) {}
Sta(int _1, int _2, int _3): x(_1), y(_2), S(_3) {}
} fa[maxn][maxn][maxs];

bool up(Sta to, Sta from, int val) {
if(f[to.x][to.y][to.S] > val) {
f[to.x][to.y][to.S] = val, fa[to.x][to.y][to.S] = from;
return 1;
}
return 0;
}

queue <Sta> Q;
bool inq[maxn][maxn];
void init() {
memset(inq, 0, sizeof(inq));
while(!Q.empty()) Q.pop();
return ;
}
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
bool inside(Sta x) {
return 1 <= x.x && x.x <= n && 1 <= x.y && x.y <= m;
}
void expend() {
while(!Q.empty()) {
Sta u = Q.front(); Q.pop(); inq[u.x][u.y] = 0;
for(int i = 0; i < 4; i++) {
Sta v(u.x + dx[i], u.y + dy[i], u.S);
if(inside(v) && up(v, u, f[u.x][u.y][u.S] + A[v.x][v.y]) && !inq[v.x][v.y])
inq[v.x][v.y] = 1, Q.push(v);
}
}
return ;
}

bool put[maxn][maxn];
void Path(Sta u) {
if(!u.S) return ;
put[u.x][u.y] = 1;
Sta v = fa[u.x][u.y][u.S];
Path(v);
if(v.S != u.S && v.S) Path(Sta(v.x, v.y, u.S - v.S));
return ;
}

int main() {

for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
for(int S = 0; S < maxs; S++)
f[i][j][S] = oo;
int p = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
if(!A[i][j]) f[i][j][1<<p++] = 0;
}
int all = (1 << p) - 1;
for(int S = 1; S <= all; S++) {
init();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
for(int Sub = S & S - 1; Sub; Sub = S & Sub - 1)
if(f[i][j][Sub] < oo && f[i][j][S-Sub] < oo)
up(Sta(i, j, S), Sta(i, j, Sub), f[i][j][Sub] + f[i][j][S-Sub] - A[i][j]);
if(f[i][j][S] < oo) Q.push(Sta(i, j, S)), inq[i][j] = 1;
}
expend();
}

for(int i = 1; i <= n; i++) {
bool has = 0;
for(int j = 1; j <= m; j++) if(!A[i][j]) {
printf("%d\n", f[i][j][all]);
Path(Sta(i, j, all));
for(int a = 1; a <= n; a++) {
for(int b = 1; b <= m; b++)
if(!A[a][b]) putchar('x');
else if(put[a][b]) putchar('o');
else putchar('_');
putchar('\n');
}
has = 1; break;
}
if(has) break;
}

return 0;
}


posted @ 2017-03-24 12:29  xjr01  阅读(198)  评论(0编辑  收藏  举报