HDU 3681
2024-09-30 23:00:51
也算难题,难在如何处理有些点可以无限次经过 问题。 这道题,其实很容易想到二分+TSP的状态压缩,但在处理上述问题时,确实没想到。题解是处理每一个Y或G或F点到其他YGF点的距离,BFS,这样就出现一个点只访问一次,而且即便在原图上重复经过某点,在重建的图也不会体现出来了。绝!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; char map[16][16];
bool vis[16][16];
int cnt,dp[1<<16][16];
struct Node{
int x,y;
}node[16];
int dis[16][16][16][16];
const int inf=(1<<30);
int n,m,fp,head,tail;
int dir[4][2]={
{0,1},
{0,-1},
{1,0},
{-1,0}
};
Node que[400];
int endfor; bool ok(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='D'&&!vis[x][y]) return true;
return false;
} void bfs(Node start){
Node tmp;
vis[start.x][start.y]=true;
que[tail++]=start;
int step=0;
while(head<tail){
int sz=tail-head;
step++;
while(sz--){
Node ss=que[head++];
for(int i=0;i<4;i++){
tmp.x=ss.x+dir[i][0];
tmp.y=ss.y+dir[i][1];
if(ok(tmp.x,tmp.y)){
if(map[tmp.x][tmp.y]=='G'||map[tmp.x][tmp.y]=='Y'){
dis[start.x][start.y][tmp.x][tmp.y]=step;
// cout<<start.x<<" "<<start.y<<" "<<tmp.x<<" "<<tmp.y<<" "<<step<<endl;
}
que[tail++]=tmp;
vis[tmp.x][tmp.y]=true;
}
}
}
}
} bool check(int bat){
memset(dp,-1,sizeof(dp));
int alt=1<<cnt;
dp[1<<fp][fp]=bat;
for(int i=0;i<alt;i++){
for(int j=0;j<cnt;j++){
if(dp[i][j]==-1) continue;
if((i&endfor)==endfor){
if(dp[i][j]!=-1) return true;
}
for(int k=0;k<cnt;k++){
if(dis[node[j].x][node[j].y][node[k].x][node[k].y]==-1) continue;
if(i&(1<<k)) continue;
if(dp[i][j]-dis[node[j].x][node[j].y][node[k].x][node[k].y]<0) continue;
int tmp=dp[i][j]-dis[node[j].x][node[j].y][node[k].x][node[k].y];
if(map[node[k].x][node[k].y]=='G') tmp=bat;
if(tmp>dp[i|(1<<k)][k]) dp[i|(1<<k)][k]=tmp;
}
}
}
return false;
} void slove(){
int l=0,r=1000;
int res=r;
while(l<=r){
int m=(l+r)/2;
if(check(m)){
res=m;
r=m-1;
}
else l=m+1;
}
if(res==1000) printf("-1\n");
else printf("%d\n",res);
} int main(){
while(scanf("%d%d",&n,&m),n||m){
cnt=0;
endfor=0;
for(int i=0;i<n;i++){
scanf("%s",map[i]);
// cout<<map[i]<<endl;
for(int j=0;j<m;j++){
if(map[i][j]=='F'){
fp=cnt;
node[cnt].x=i,node[cnt].y=j;
cnt++;
}
else if(map[i][j]=='G'){
node[cnt].x=i,node[cnt].y=j;
cnt++;
}
else if(map[i][j]=='Y'){
node[cnt].x=i,node[cnt].y=j;
endfor+=(1<<cnt);
cnt++;
}
}
}
memset(dis,-1,sizeof(dis));
for(int i=0;i<cnt;i++){
head=tail=0;
memset(vis,false,sizeof(vis));
bfs(node[i]);
}
slove();
}
return 0;
}
最新文章
- 浅谈Android中拍照、从相册选择图片并截图相关知识点
- java考核完的心得
- 0.AutoMapper核心
- 走进异步编程的世界 - 开始接触 async/await
- velocity模板引擎学习(4)-在standalone的java application中使用velocity及velocity-tools
- boi剖析 - 基于webpack的css sprites实现方案
- 《MySQL必知必会》笔记 事务、安全及性能等
- factory工厂模式之简单工厂SimpleFactory
- Android应用框架浅析
- ActionResult
- POJ1013Counterfeit Dollar
- SOAP 及其安全控制--转载
- linux 开机自动挂载ntfs盘
- 简单的完全背包HDU1114
- canvas+gif.js打造自己的数字雨头像
- centos添加开放端口
- 接口测试工具-tamper data
- 论文笔记:Learning Attribute-Specific Representations for Visual Tracking
- unit3d 初次接触
- 迭代dict的value