zoukankan      html  css  js  c++  java
  • 变色龙(Floyd算法)

    变色龙

      避役(学名:Chamaeleonidae)(英语:chameleon)俗称变色龙,蜥蜴亚目(Sauria)避役科(Chamaeleontidae)爬行类,产于东半球。特征为体色能变化,它在每天会进行变色,可以变成N种颜色之一,将这些颜色标号为0,1,2...N-1。最近研究发现变色龙不是靠色素细胞变色,而是靠体内的基因,变色龙的基因内存在一个变色矩阵,记为Genemap,如果Genemap[i][j] = 'Y',则变色龙可以在某天从颜色i变成颜色j(一天不可以变色多次),如果Genemap[i][j] =‘N’则不能从i变成j色。最新又发现,变色龙的变色不是任意变的,它有一定的规律,这个规律是在某天,如果只有一种可以改变的颜色,它就变为这种颜色,如果有多种可以改变的颜色,那么它变为标号最小的颜色,如果不存在任何一种可以改变的颜色,那就不变色,注意可以变色时它一定会变色。小明在淘宝上买了一只颜色为0的变色龙,他想让这只变色龙变为颜色N-1,然后他向当地医院求助,医生有一项技术可以改变变色龙的一些基因,但需要花费高昂的代价,具体说小明可以花费1万元的代价,让医生将变色龙的变色矩阵中的某一个Genemap[i][j] = 'Y'改变成Genemap[i][j] = 'N'。问至少花费多少总代价改变变色龙的基因,让变色龙按它的变色规律可以从颜色0经过若干天的变色变成颜色N-1。如果一定不能变成N-1,则输出-1.

    Input

    第一行一个整数T(1<=T<=5),表示测试数据数量,每组测试数据有相同的结构构成: 每组数据第一行一个整数N(2<=N<=50)。 之后有N行,每行N个字符,表示变色龙的变色矩阵,矩阵中只有‘Y’与‘N’两种字符,第i行第j列的字符就是Genemap[i][j]。

    Output

    每组数据一行输出,即最小代价,无解时输出-1

    Sample Input 1 

    3
    3
    NYN
    YNY
    NNN
    8
    NNNNNNNY
    NNNNYYYY
    YNNNNYYN
    NNNNNYYY
    YYYNNNNN
    YNYNYNYN
    NYNYNYNY
    YYYYYYYN
    6
    NYYYYN
    YNYYYN
    YYNYYN
    YYYNYN
    YYYYNN
    YYYYYN

    Sample Output 1

    1
    0
    -1
    题解:要想从颜色i变成颜色j,需要Genemap[i][0]到Genemap[i][j-1]没有出现Y,如果出现,需改成N,即两点之间的花费加一。转化为求
    Genemap[i][0]到Genemap[i][j]的最短路问题。
    特别注意Floyd算法中三重循环i,j,k的顺序。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define inf 0x3f3f3f3f
     6 using namespace std;
     7 const int maxn=100;
     8 char s[maxn][maxn];
     9 int map[maxn][maxn];
    10 int main()
    11 {
    12     int n,casen;
    13     cin>>casen;
    14     while(casen--)
    15     {
    16         memset(map,inf,sizeof(map));
    17         scanf("%d",&n);
    18         for(int i=0;i<n;i++)
    19         {
    20             int cnt=0;
    21             scanf("%s",s[i]);
    22             for(int j=0;j<n;j++)
    23             {
    24                 if(s[i][j]=='Y')
    25                     map[i][j]=cnt++;
    26             }
    27         }
    28         for(int k=0;k<n;k++)//从i到j的最短距离需要经过0-n-1顶点进行中转
    29         {
    30             for(int i=0;i<n;i++)
    31             {
    32                 for(int j=0;j<n;j++)
    33                 {
    34                     if(map[i][j]>map[i][k]+map[k][j])
    35                         map[i][j]=map[i][k]+map[k][j];
    36                 }
    37             }
    38         }
    39         if(map[0][n-1]==inf)
    40             printf("-1
    ");
    41         else
    42             printf("%d
    ",map[0][n-1]);
    43     }
    44 return 0;
    45 }
     
  • 相关阅读:
    LeetCode 139. Word Break
    Amazon behavior question
    学习笔记之100 TOP Ikm C++ Online Test Questions
    学习笔记之IKM C++ 11
    学习笔记之C/C++指针使用常见的坑
    LeetCode 208. Implement Trie (Prefix Tree)
    队列 & 栈//岛屿的个数
    队列 & 栈//设计循环队列
    队列 & 栈//设计循环队列
    查找表类算法//存在重复元素 III
  • 原文地址:https://www.cnblogs.com/1013star/p/9558649.html
Copyright © 2011-2022 走看看