Description
1944年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩。瑞恩被关押在一个迷宫里,迷宫地形复杂,但是幸好麦克得到了迷宫的地形图。迷宫的外形是一个长方形,其在南北方向被划分为
N
行,在东西方向被划分为
Input
第一行是三个整数,依次表示
N,M,P
的值;
第二行是一个整数
K
,表示迷宫中门和墙的总个数;
第
当
Gi>=1
时,表示
(Xi1,Yi1)
单元与
(Xi2,Yi2)
单元之间有一扇第
Gi
类的门,
当
Gi=0
时,表示
(Xi1,Yi1)
单元与
(Xi2,Yi2)
单元之间有一堵不可逾越的墙;
(其中,
|Xi1−Xi2|+|Yi1−Yi2|=1
,
0<=Gi<=P
)
第
K+3
行是一个整数
S
,表示迷宫中存放的钥匙总数;
第
表示第J把钥匙存放在
(Xi,Yi)
单元里,并且第
J
把钥匙是用来开启第
注意:输入数据中同一行各相邻整数之间用一个空格分隔。
3<=N,M<=15
;
1<=P<=10
;
Output
输出文件只包含一个整数
T
,表示麦克营救到大兵瑞恩的最短时间的值,若不存在可行的营救方案则输出-1。
Sample Input
4 4 9
9
1 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
2
2 1 2
4 2 1
Sample Output
14
HINT
思路
设
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn=15;
const int maxp=10;
const int inf=0x3f3f3f3f;
const int dx[]= {1,0,-1,0};
const int dy[]= {0,1,0,-1};
struct data
{
int x,y,s;
};
int kind[maxn+1][maxn+1][4],n,m,p,k,s,tot,ans=inf;
int pre[maxn*maxn*(1<<maxp)+10],now[maxn+1][maxn+1][1<<maxp];
data son[maxn*maxn*(1<<maxp)+10];
int val[maxn*maxn*(1<<maxp)+10],b[maxn+1][maxn+1][1<<maxp];
int dist[maxn+1][maxn+1][1<<maxp],head,tail;
data q[maxn*maxn*(1<<maxp)*4+10];
int check_position(int a,int b,int c)
{
return (a==dx[c])&&(b==dy[c]);
}
int in_range(int a,int b)
{
return (a>0)&&(a<=n)&&(b>0)&&(b<=m);
}
int makewall(int a,int b,int c,int d,int k)
{
for(int i=0; i<4; i++)
{
if(check_position(c-a,d-b,i))
{
if(!k)
{
kind[a][b][i]=-1;
}
else
{
kind[a][b][i]=k;
}
}
}
return 0;
}
int ins(int ax,int ay,int as,int bx,int by,int bs,int c)
{
tot++;
pre[tot]=now[ax][ay][as];
now[ax][ay][as]=tot;
son[tot].x=bx;
son[tot].y=by;
son[tot].s=bs;
val[tot]=c;
return 0;
}
int spfa(int sx,int sy,int ss)
{
memset(dist,63,sizeof dist);
head=0;
tail=1;
q[1].x=sx;
q[1].y=sy;
q[1].s=ss;
b[sx][sy][ss]=1;
dist[sx][sy][ss]=0;
while(head!=tail)
{
head++;
int ux=q[head].x,uy=q[head].y,us=q[head].s;
int j=now[ux][uy][us];
while(j)
{
int vx=son[j].x,vy=son[j].y,vs=son[j].s;
if(dist[vx][vy][vs]>dist[ux][uy][us]+val[j])
{
dist[vx][vy][vs]=dist[ux][uy][us]+val[j];
if(!b[vx][vy][vs])
{
b[vx][vy][vs]=1;
tail++;
q[tail].x=vx;
q[tail].y=vy;
q[tail].s=vs;
}
}
j=pre[j];
}
b[ux][uy][us]=0;
}
return 0;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&p,&k);
for(int i=1; i<=k; i++)
{
int a,b,c,d,e;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
makewall(a,b,c,d,e);
makewall(c,d,a,b,e);
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
for(int k=0; k<4; k++)
{
if(in_range(i+dx[k],j+dy[k]))
{
if(kind[i][j][k]==0)
{
for(int l=0; l<1<<p; l++)
{
ins(i,j,l,i+dx[k],j+dy[k],l,1);
}
}
if(kind[i][j][k]>0)
{
for(int l=0; l<1<<p; l++)
{
if((l|(1<<(kind[i][j][k]-1)))==l)
{
ins(i,j,l,i+dx[k],j+dy[k],l,1);
}
}
}
}
}
}
}
scanf("%d",&s);
for(int i=1; i<=s; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
for(int l=0; l<1<<p; l++)
{
if((l|(1<<(c-1)))!=l)
{
ins(a,b,l,a,b,l|(1<<(c-1)),0);
}
}
}
spfa(1,1,0);
for(int i=0; i<1<<p; i++)
{
ans=std::min(ans,dist[n][m][i]);
}
if(ans==inf)
{
puts("-1");
return 0;
}
printf("%d\n",ans);
return 0;
}