1. 程式人生 > >杭電(hdu)1181 變形課

杭電(hdu)1181 變形課

pac ems out 成了 problem mar acc 順序 silver

變形課

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 18343 Accepted Submission(s): 6597


Problem Description 呃......變形課上Harry碰到了一點小麻煩,由於他並不像Hermione那樣可以記住全部的咒語而任意的將一個棒球變成刺猬什麽的,可是他發現了變形咒語的一個統一規律:假設咒語是以a開頭b結尾的一個單詞,那麽它的作用就恰好是使A物體變成B物體.
Harry已經將他所會的全部咒語都列成了一個表,他想讓你幫忙計算一下他能否完畢老師的作業,將一個B(ball)變成一個M(Mouse),你知道,假設他自己不能完畢的話,他就僅僅好向Hermione請教,而且被迫聽一大堆好好學習的道理.

Input 測試數據有多組。每組有多行,每行一個單詞,僅包含小寫字母,是Harry所會的全部咒語.數字0表示一組輸入結束.

Output 假設Harry能夠完畢他的作業,就輸出"Yes.",否則就輸出"No."(不要忽略了句號)

Sample Input
so
soon
river
goes
them
got
moon
begin
big
0

Sample Output
Yes.

HintHint 
Harry 能夠念這個咒語:"big-got-them".
先來介紹下floyd算法:

讓我們來看一個樣例,看下圖:

技術分享

圖中紅色的數字代表邊的權重。

假設我們在最內層檢查全部節點X。那麽對於A->B,我們僅僅能發現一條路徑,就是A->B,路徑距離為9。而這顯然是不對的,真實的最短路徑是A->D->C->B,路徑距離為6。造成錯誤的原因就是我們把檢查全部節點X放在最內層,造成過早的把A到B的最短路徑確定下來了,當確定A->B的最短路徑時Dis(AC)尚未被計算。所以,我們須要改寫循環順序,例如以下:

for ( int k = 0; k < 節點個數; ++k ) { for ( int i = 0; i < 節點個數; ++i ) { for ( int j = 0; j < 節點個數; ++j ) { if ( Dis[i][k] + Dis[k][j] < Dis[i][j] ) {
// 找到更短路徑 Dis[i][j] = Dis[i][k] + Dis[k][j]; } } } }

這樣一來,對於每個節點X。我們都會把全部的i到j處理完成後才繼續檢查下一個節點。

代碼例如以下:
#include<iostream>  
#include<cstring>  
#include<string>
#include<cstdio>  
using namespace std;  
int weight[30][30];  
void floyd()
{
    for(int t=0;t<26;t++)
        for(int i=0;i<26;i++)
            for(int j=0;j<26;j++)
                if(weight[i][t]&&weight[t][j])
                    weight[i][j]=1;
}  
int main()
{  
    char s[100];  
    while(gets(s))
    {  
        memset(weight,0,sizeof(weight));  
        while(s[0]!=‘0‘)
        {
            weight[s[0]-‘a‘][s[strlen(s)-1]-‘a‘]=1;
            gets(s);
        }
        floyd();
        if(weight[1][12])
            printf ("Yes.\n");  
        else
            printf ("No.\n");  
    }  
}  

杭電(hdu)1181 變形課