題面:話說Z4陰差陽錯地來到了神祕島。不久,他們發現,這是一個由n個小島和一箇中心島組成的羣島,羣島之間有m座橋。令他們感到驚訝的是,這些橋並不是固定不變的,經較長時間的觀察,發現它們會隨時間作週期性的變化(即橋的兩端會不斷更換)。
立方很早就留意到遠遠的那個中心島了。他發現島的上空好像有一個很巨大的東西,但實在太遠了,看不清楚。此時jakrinchose得意地從身上拿出一個超高倍數望遠鏡,好像很自豪的樣子,因爲他平時專門用來看美女的工具此時終於派得上用場了。
“那是一間小屋!架在一棵好大好大的樹上!”
“Terrific!我們也許可以暫時在那安頓,好用來遮風避雨!”
於是他們便決定前往中心島上的那間空中樓閣。Z4的懶惰是出了名的,他們當然希望越早到越好,那麼,你能幫幫他們嗎?
爲方便計算,Z4把小島按1..n編號,0表示中心島。Z4一開始在編號爲1的小島上。在島上行走的時間忽略不計,過橋的時間爲1個單位。島上的橋變化的週期爲T,在nT+i(n=0,1,2,…;i=1,2,…,T)時刻島上的橋爲第i種狀態,一開始的時刻爲1。兩個小島間可能有多條橋相連。在任一時刻,Z4可以選擇過橋,也可以原地不動。當然,如果無橋可過,Z4只能在原地等待。
【輸入格式】
輸入文件house.in的第一行包括三個整數n(1<=n<=80),m(1<=m<=10000)和T(1<=T<=10),分別表示小島的個數,島上橋的數量和橋改變的週期T。
接下來分別描述第1..T種狀態,每種狀態有m行,每行有兩個整數a, b(0<=a,b<=n),表示這種狀態時小島a和b有一條橋相連。兩狀態之間用一空行隔開。
【輸出格式】
輸出文件house.out僅有一個整數,表示Z4最少得花多少時間到達中心島。如果Z4無法到達中心島,則輸出“Poor Z4!”。
【輸入樣例1】
4 5 2
1 2
1 3
1 4
2 0
4 0
1 3
1 3
2 3
4 3
3 0
【輸出樣例1】
2
【輸入樣例2】
7 3 2
1 2
1 4
6 0
2 5
3 6
4 7
【輸出樣例2】
Poor Z4!
這題其實是spfa,比一般的最短路多出了一維是記錄時間;
map[i][j][k]表示時刻爲k時 i是否可以到達j;
dis[i][j]表示在時刻j到達點i的最小值;
#include<bits/stdc++.h>
#define N 100
using namespace std;
int Map[N][N][N],dis[N][N],n,m,T;bool limit[N][N];
struct node{
int id,ti;
};inline void spfa(){
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
dis[i][j]=20021109;
queue<node>q;q.push(node{1,0});dis[1][0]=0;limit[1][0]=1;
while(!q.empty()){
int u=q.front().id,t=q.front().ti;
q.pop();limit[u][t]=0;
int tt=(t+1)%T;
for(int i=0;i<=n;i++){
if(!Map[u][i][t])continue;//注意當前時刻是t,而不是tt
if(dis[u][t]+1<dis[i][tt]){
dis[i][tt]=dis[u][t]+1;
if(!limit[i][tt]){
limit[i][tt]=1;
q.push(node{i,tt});
}
}
}
}
}int main(){int x,y;
// freopen("house.in","r",stdin);
// freopen("house.out","w",stdout);
scanf("%d%d%d",&n,&m,&T);
for(int i=0;i<T;i++)
for(int j=1;j<=m;j++){
scanf("%d%d",&x,&y);
Map[x][y][i]=Map[y][x][i]=1;//記錄是否能到達
}for(int i=0;i<T;i++)
for(int j=0;j<=n;j++)
Map[j][j][i]=1;
spfa();int res=20021109;
for(int i=0;i<T;i++)res=min(res,dis[0][i]);//找到到0的最小值
if(res>=20021109)puts("Poor Z4!");
else printf("%d",res);
}