您的位置:首页 > 其它

Bzoj2595: [Wc2008]游览计划

2017-01-20 23:23 316 查看
Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special Judge
Submit: 1463  Solved: 679
[Submit][Status][Discuss]

Description

Input

第一行有两个整数,N和 M,描述方块的数目。 
接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点;
否则表示控制该方块至少需要的志愿者数目。 相邻的整数用 (若干个) 空格隔开,
行首行末也可能有多余的空格。

Output


由 N + 1行组成。第一行为一个整数,表示你所给出的方案
中安排的志愿者总数目。 
接下来 N行,每行M 个字符,描述方案中相应方块的情况: 
z  ‘_’(下划线)表示该方块没有安排志愿者; 
z  ‘o’(小写英文字母o)表示该方块安排了志愿者; 
z  ‘x’(小写英文字母x)表示该方块是一个景点; 
注:请注意输出格式要求,如果缺少某一行或者某一行的字符数目和要求不
一致(任何一行中,多余的空格都不允许出现) ,都可能导致该测试点不得分。

Sample Input

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



Sample Output

6
xoox
___o
___o
xoox

HINT

 

 对于100%的数据,N,M,K≤10,其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内

 

Source

Ljcc930提供SPJ

 

斯坦纳树。

记录状态简直恶心。

 

炸了好久好久,最后发现是第81行初始化的时候x=INF写成了w=INF

↑白弄了好久的标准代码比对

/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int mx[5]={0,1,0,-1,0};
const int my[5]={0,0,1,0,-1};
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int mp[15][15];
int n,m,k;
int id[15];
int f[15][15][1100];
struct pt{
int x,y,w;
}p[15][15][1100];
queue<pair<int,int> >q;
bool vis[30][30];
void SPFA(int s){
while(!q.empty()){
int x=q.front().first;
int y=q.front().second;
q.pop();
vis[x][y]=0;
for(int k=1;k<=4;k++){
int nx=x+mx[k],ny=y+my[k];
if(nx<1 || nx>n || ny<1 || ny>m)continue;
if(f[nx][ny][s]>f[x][y][s]+mp[nx][ny]){
f[nx][ny][s]=f[x][y][s]+mp[nx][ny];
p[nx][ny][s]=(pt){x,y,s};
if(!vis[nx][ny]){
q.push(make_pair(nx,ny));
vis[nx][ny]=1;
}
}
}
}
return;
}
void DFS(int x,int y,int s){//标记路径
if(x>=INF || !p[x][y][s].w)return;
vis[x][y]=1;
DFS(p[x][y][s].x,p[x][y][s].y,p[x][y][s].w);
if(p[x][y][s].x==x && p[x][y][s].y==y)DFS(p[x][y][s].x,p[x][y][s].y,s-p[x][y][s].w);
return;
}
void Print(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!mp[i][j])printf("x");
else if(!vis[i][j])printf("_");
else printf("o");
}
printf("\n");
}
return;
}
int main(){
int i,j;
n=read();m=read();k=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
mp[i][j]=read();
if(!mp[i][j])k++;
}
//
memset(f,0x3f,sizeof f);
for(i=1;i<=k;i++)id[i]=1<<(i-1);
int ed=(1<<k)-1;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(int c=0;c<=ed;c++)
p[i][j][c].x=INF;
//init
k=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(!mp[i][j]){
f[i][j][id[++k]]=0;
}
for(int s=1;s<=ed;s++){
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
for(int c=(s-1)&s;c;c=(c-1)&s){
if(f[i][j][s]>f[i][j][c]+f[i][j][s-c]-mp[i][j]){
f[i][j][s]=f[i][j][c]+f[i][j][s-c]-mp[i][j];
p[i][j][s]=(pt){i,j,c};
}
}
if(f[i][j][s]<INF){
q.push(make_pair(i,j));
vis[i][j]=1;
}
}
SPFA(s);
}
memset(vis,0,sizeof vis);
while(!q.empty())q.pop();
for(i=n;i;i--)
for(j=m;j;j--){
if(!mp[i][j]){
DFS(i,j,ed);
printf("%d\n",f[i][j][ed]);
Print();
return 0;
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: