VIJOS-P1406 古韵之鹊桥相会 最短路 模型

我继续

题目描述

这题乍一看就是一天天消消乐。。。。我一看就乐了。。。。
只不过这次不全都消下去而已 只需要最快的到达对岸

最快 我们想到了最短路算法
由于数据太小了 可以用邻接矩阵 我们不妨给每一个点一个编号cnt
那么f[i][j]表示cnt为I和cnt为j的点之间的最路径是多少
如果两个点挨着
那么就f[i][j]=0
否则 f[i][j]=1;
对于那些并不能联通的点 f[i][j]=inf;
所以下一步你们就放心大胆的跑floyd就行了
建图是N方的
对每个点的处理是接近线性的

所以合起来也就是一个N立方的复杂度
重要的是建图
建完图之后你跑什么都行。。。什么spfa dij Floyd 随意了
但是还是floyd是比较简单的

这里还有一个优化
我们可以设置一个终极起点 到第一排的每个点的距离为0其余为inf
同理也可以设置一个终极重点。。。。。
下面是我的代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 400+5
int map[N][N],n,m;
char str[N][N];
void check(int i,int j,int cnt)
{
    if (str[i][j]==str[i][j+1]&&j+1<=m)
        map[cnt][cnt+1]=map[cnt+1][cnt]=0;
    else if(str[i][j]!=str[i][j+1]&&j+1<=m)
        map[cnt][cnt+1]=map[cnt+1][cnt]=1;
    if (str[i][j]==str[i][j-1]&&j-1>0)
        map[cnt][cnt-1]=map[cnt-1][cnt]=0;
    else if(str[i][j]!=str[i][j-1]&&j-1>0)
        map[cnt][cnt-1]=map[cnt-1][cnt]=1;
    if (str[i][j]==str[i-1][j]&&i-1> 0&&cnt-m>0)
        map[cnt][cnt-m]=map[cnt-m][cnt]=0;
    else if(str[i][j]!=str[i-1][j]&& i-1>0 && cnt-m>0)
        map[cnt][cnt-m]=map[cnt-m][cnt]=1;
    if (str[i][j]==str[i+1][j]&&i+1<=n)
        map[cnt][cnt+m]=map[cnt+m][cnt]=0;
    else if(str[i][j]!=str[i+1][j]&&i+1<=n)
        map[cnt][cnt+m]=map[cnt+m][cnt]=1;
}
int main()
{

    cin>>n>>m;
    int cnt=0;
    memset(map,0x3f,sizeof map);
    for(int i=1;i<=n;++i)
        scanf("%s",str[i]+1);   
    for(int i=1;i<=m;++i)
        map[cnt][i]=0;
    int end=n*m+1;
    for(int i=(n-1)*(m)+1;i<=n*m;++i)
        map[i][end]=0;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            check(i,j,++cnt);
    for(int k=0;k<=cnt+1;++k)
        for(int i=0;i<=cnt+1;++i)
            for(int j=0;j<=cnt+1;++j)
                map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
    cout<<map[0][end]+1;
} 

VIJOS-P1406 古韵之鹊桥相会 最短路 模型_第1张图片

你可能感兴趣的:(算法,最短路,vijos)