首页 > 代码库 > voj 1406 floyd

voj 1406 floyd

传说,上古时期的某个七月七日,王母娘娘为了阻止牛郎织女的爱情,划一道玉钗拆散鸳鸯,使两人“星桥鹊驾,经年才见,想离情、别恨难穷。”于是,“执子之手,与子偕老”成了天下有情人共同的希翼。

在气宇轩昂、玉树临风、才高八斗、英俊潇洒的程文大牛的期盼中,浪漫又迷人的七夕终于来临了。迷离的夜空之上,牛郎织女的絮语伴随着美好的秋光,浸润了古今文人墨客多情的心。他与美若天仙、唇红齿白、蕙质兰心、冰雪聪明的某MM约好在清江的小桥上相会…… 天亦有情,此时,浮云错开,从天而降一张丝绸地图:正面上,不同颜色的星星组成了前方道路的俯视图;背面写着“愿有情人终成眷属,无伴者皆得幸福。——瑾姝”。

程文仔细看着这个图,发现自己必须从上到下打通一条道路才能见到某MM,于是程文决定用排云掌和风神腿打开前方的道路—— 现用不同的字母来表示不同颜色的星星,连在一起(水平或竖直相邻才算连在一起)的相同颜色的星星,程文可以一次性全部打掉。

图样如下: AABBCCD AFFBGGD IIJBKKD MNNOOPD QQRRSST 比如在这张地图中,程文可以先打掉最右边的D区域,然后再打通T区域,这样就只用两次就可以打通道路(道路是可以拐弯的,不一定要是一条直线)。

因为使用排云掌和风神腿会耗费体力,耗费干净了程文就没法陪MM一起玩了,所以程文想用最少的次数来打通这条道路,不过程文现在跑去学Java了,这件事就交给你了。

格式

输入格式

第一行有两个整数,m和n(0<m,n<21); 下面m行,每行n个字母。

输出格式

一个整数,程文打通道路用功力的最少的次数。

样例1

样例输入1

5 7
AABBCCD
AFFBGGD
IIJBKKD
MNNOOPD
QQRRSST

样例输出1

2
一开始看错题意,题目意思是只要是符号相同的,即使出现拐角也能一次性打完.
e[i][j][x][y]表示(i,j)-->(x,y)的最短路径,对于每个点对其四个方向建边,符号相同的边权为0,否则为1,最后跑一遍
floyd之后遍历得到答案.

 #include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
char ch[25][25];
int e[25][25][25][25];
int n,m;
int fx[4][2]={1,0,-1,0,0,1,0,-1};
int main()
{
    int i,j,k,s,x,y,ans=inf;
    for(i=0;i<21;++i)
       for(j=0;j<21;++j)
          for(x=0;x<21;++x)
            for(y=0;y<21;++y){
    if(i==x&&j==y) e[i][j][x][y]=0;
    else e[i][j][x][y]=inf;
    }
    cin>>m>>n;
    for(i=1;i<=m;++i)
        for(j=1;j<=n;++j) cin>>ch[i][j];
    for(i=1;i<=m;++i)
        for(j=1;j<=n;++j)
           for(k=0;k<4;++k)
    {
        int _x=i+fx[k][0];
        int _y=j+fx[k][1];
        if(_x>0&&_y>0&&_x<=m&&_y<=n)
                 e[i][j][_x][_y]=(ch[i][j]==ch[_x][_y]?0:1);

    }
    int k1,k2;
for(k1=1;k1<=m;++k1)
      for(k2=1;k2<=n;++k2)
        for(i=1;i<=m;++i)
          for(j=1;j<=n;++j)
            for(x=1;x<=m;++x)
              for(y=1;y<=n;++y)
    {
        e[i][j][x][y]=min(e[i][j][x][y],e[i][j][k1][k2]+e[k1][k2][x][y]);
    }

    for(i=1;i<=n;++i)
        for(j=1;j<=n;++j) {
                ans=min(ans,e[1][i][m][j]);
        }
    cout<<ans+1<<endl;
    return 0;
}

voj 1406 floyd