链接: 原题链接
输入输出样例
输入 #1
5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0
输出 #1
8
输入 #2
5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0
输出 #2
-1
说明/提示
输入输出样例 1 说明
输入输出样例 2 说明
思路讲解
本题与“回家”题十分相似,都是最短路的拓展类型。
本题要求的是花费的最少金币。思路比较容易,根据每一格子的颜色往下搜索即可。但是要注意剪枝,不然会TLE。
代码实现
#include<bits/stdc++.h>
using namespace std;
const int MAXN=105;
int m,n;
int flag,sum;
int a[MAXN][MAXN],v[MAXN][MAXN],f[MAXN][MAXN];
int minn=0x3f3f3f3f;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
void DFS(int x,int y,int sum,bool frog);//走到某个位置(包括这个位置)已经花费了多少
//frog 为 true 则已经使用过魔法
int main()
{
scanf("%d%d",&m,&n);
int ti,tj,c;
memset(a,-1,sizeof(a));
memset(v,0,sizeof(v));
memset(f, 0x7f, sizeof(f));
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&ti,&tj,&c);
a[ti][tj]=c;
}
v[1][1]=1;
DFS(1,1,0,false);
if(flag)printf("%d",minn);
else printf("-1");
}
void DFS(int x,int y,int sum,bool frog)
{
if(x==m&&y==m)
{
flag=1;
if(sum<minn)
minn=sum;
return;
}
if(sum>minn) return;//剪枝
if(sum>=f[x][y])return; //储存最优解
else f[x][y]=sum;
int tx,ty;
for(int i=0;i<=3;i++)
{
tx=x+dx[i];
ty=y+dy[i];
if(tx<1||tx>m||ty<1||ty>m)continue;//防止越界
if(a[tx][ty]!=-1&&v[tx][ty]==0)//下一格有颜色
{
if(a[tx][ty]==a[x][y])
{
v[tx][ty]=1;
DFS(tx,ty,sum,false);
v[tx][ty]=0;
}
if(a[tx][ty]!=a[x][y])
{
v[tx][ty]=1;
DFS(tx,ty,sum+1,false);
v[tx][ty]=0;
}
}
else //无颜色
{
if(!frog&&v[tx][ty]==0)
{
v[tx][ty]=1;
a[tx][ty]=a[x][y]; //使用魔法后将无色格子的颜色变为与上一格子相同的颜色
DFS(tx,ty,sum+2,true);
v[tx][ty]=0;
a[tx][ty]=-1; //回溯时复原无色格子
}
}
}
}
继续加油!