最短路。
给出的地图中,Y为起点,C为终点,#点不能通过,可直接忽略。所有的P为互通的传送门,故可将所以的P看作同一个点。每个能通过的点可以向上下左右四个方向走,如果对应的方向可以通过,则连边,若要走到的点是*,则边权为通过的费用,否则边权为0。
连边后求Y到C的最短路即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
//int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int vis[300][300];
int map[300][300];
int xx[] = {0, 0, 1, -1};
int yy[] = {1, -1, 0, 0};
struct Node
{
int rr,cc;
};
Node p[300*300];
Node ed;
struct poi
{
int rr,cc;
int val;
};
poi start;
int r,c,v;
int k;
int inmap(int r1,int c1)
{
if(r1>=1&&r1<=r&&c1>=1&&c1<=c)
return 1;
else
return 0;
}
int bfs(poi s)
{
queue<poi>qu;
while(!qu.empty())
qu.pop();
qu.push(s);
vis[s.rr][s.cc]=1;
int ans=-1;
while(!qu.empty())
{
poi cur,nex;
cur=qu.front();
qu.pop();
if(cur.rr==ed.rr&&cur.cc==ed.cc)
{
ans=cur.val;
break;
}
for(int i=0;i<4;i++)
{
nex.rr=cur.rr+xx[i];
nex.cc=cur.cc+yy[i];
if(!inmap(nex.rr,nex.cc)||vis[nex.rr][nex.cc]||!map[nex.rr][nex.cc])
continue;
else if(map[nex.rr][nex.cc]==2)
{
for(int j=0;j<k;j++)
{
nex.rr=p[j].rr;
nex.cc=p[j].cc;
nex.val=cur.val;
vis[p[j].rr][p[j].cc]=1;
qu.push(nex);
}
}
else
{
nex.val=cur.val+1;
vis[nex.rr][nex.cc]=1;
qu.push(nex);
}
}
}
return ans;
}
int main()
{
char ch;
while(scanf("%d%d%d",&r,&c,&v)!=EOF)
{
k=0;
memset(vis,0,sizeof(vis));
memset(map,0,sizeof(map));
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
cin>>ch;
if(ch=='Y')
{start.rr=i;start.cc=j;start.val=0;map[i][j]=1;}
if(ch=='C')
{ed.rr=i;ed.cc=j;map[i][j]=1;}
if(ch=='#')
map[i][j]=0;
if(ch=='P')
{p[k].rr=i;p[k].cc=j;k++;map[i][j]=2;}
if(ch=='*')
map[i][j]=1;
}
getchar();
}
int ans=bfs(start);
if(ans != -1)
printf("%d\n", (ans - 1) * v);
else
printf("Damn teoy!\n");
}
return 0;
}
多校第一场:hdu 4308(bfs)
最新推荐文章于 2022-07-19 18:47:51 发布