封印之門(最短路)

shaonianbz發表於2018-03-27

問題

蒜頭君被暗黑軍團包圍在一座島上,所有通往近衛軍團的路都有暗黑軍團把手。幸運的是,小島上有一扇上古之神打造的封印之門,可以通往近衛軍團,傳聞至今沒有人能解除封印。

封印之門上有一串文字,只包含小寫字母,有 k 種操作規則,每個規則可以把一個字元變換成另外一個字元。經過任意多次操作以後,最後如果能把封印之門上的文字變換成解開封印之門的文字,封印之門將會開啟。

蒜頭君戰鬥力超強,但是不擅計算,請你幫忙蒜頭君計算至少需要操作多少次才能解開封印之門

輸入格式

輸入第一行一個字串,長度不大於1000,只包含小寫字母,表示封印之門上的文字。

輸入第二行一個字串,只包含小寫字母,保證長度和第一個字串相等,表示能解開封印之門的文字。

輸入第三行一個整數k(0≤k≤676)。

接下來k行,每行輸出兩個空格隔開的字元a, b,表示一次操作能把字元a變換成字元b。

輸出格式

如果蒜頭君能開啟封印之門,輸出最少的操作次數。否則輸出一行−1。

樣例輸入

abcd
dddd
3
a b
b c
c d

樣例輸出

6

思路:

這是最短路問題,
可以參考:最短路詳解

程式碼實現

public class Main16 {
    //表示封印之門上的字母
    static char[] c1=new char[1005];  
    //表示解開封印之門的文字
    static char[] c2=new char[1005];
    //陣列
    static int[][] e=new int[30][30];
    public static void init() {//初始化   
        for(int i = 1; i <= 26; i++) {  
            for(int j = 1; j <= 26; j++) {  
                if(i == j) e[i][j] = 0;//兩個相同的字母互相轉化不需要步數   
                else e[i][j]=1000000;       //初始將兩個字母之間的轉化賦值為1000000
            }  
        }  
    }  
    public static void Floyd() {//跑最短路   
        for(int k = 1; k <= 26; k++) {  
            for(int i = 1; i <= 26; i++) {  
                for(int j = 1; j <= 26; j++) {  
                    if(i == j) continue;  
                    if(e[i][j] > e[i][k] + e[k][j])  
                        e[i][j] = e[i][k] + e[k][j];  
                }  
            }  
        }     
    }
    public static void main(String[] args) {
        int n;  
        char C1, C2;
        Scanner sc=new Scanner(System.in);
        String str1=sc.next();
        c1=str1.toCharArray();
        String str2=sc.next();
        c2=str2.toCharArray();
        n=sc.nextInt();
        init();  
        long sum = 0;  
        while(n!=0) {  
            C1=sc.next().charAt(0);
            C2=sc.next().charAt(0);
            //有可能輸入兩個字母是相同的(字母相同表示自己到自己的距離為0,不是1)
            if(C1 != C2)  
            e[C1-'a'+1][C2-'a'+1] = 1;//建圖
            n--;
        }  
        Floyd();   
        int m = c1.length;  
        //從0開始,計算c[i]
        for(int i = 0; i < m; i++) {  
            //如果沒有對應路徑,則兩點之間的距離為初始化的距離
            sum += e[c1[i]-'a'+1][c2[i]-'a'+1];//求出步數   
        }  
        if(sum<1000000){
            System.out.println(sum);
        }else{
            //沒有找到時,由於初始化為1000000,所有會大於1000000
            System.out.println(-1);
        }
    }
}

相關文章