1. 程式人生 > >【最短路】白銀蓮花池

【最短路】白銀蓮花池

empty 表示 觀察 可能 string 路徑 tput farmer 分割

Description

Farmer John 建造了一個美麗的池塘,用於讓他的牛們審美和鍛煉。這個長方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方形格子的 。某些格子上有驚人的堅固的蓮花,還有一些巖石,其余的只是美麗,純凈,湛藍的水。
貝茜正在練習芭蕾舞,她從一個蓮花跳躍到另一個蓮花,當前位於一個蓮花。她希望在蓮花上一個一個的跳,目標是另一個給定蓮花。她能跳既不入水,也不到一個巖石上。
令門外漢驚訝的是,貝茜的每次的跳躍像中國象棋的馬一樣:橫向移動1,縱向移動2,或縱向移動1,橫向移動2。貝茜有時可能會有多達8個選擇的跳躍。
Farmer John 在觀察貝茜的芭蕾舞聯系,他意識到有時候貝茜有可能跳不到她想去的目的地,因為路上有些地方沒有蓮花。於是他想要添加幾個蓮花使貝茜能夠完成任務。一貫節儉的Farmer John想添加最少數量的蓮花。當然,蓮花不能放在石頭上。
請幫助Farmer John確定必須要添加的蓮花的最少數量。在添加的蓮花最少基礎上,算出貝茜從起始點跳到目標點需要的最少的步數。最後,還要算出滿足添加的蓮花的最少數量時,跳躍最少步數的跳躍路徑的條數。

Input

? 第 1 行: 兩個整數 M , N
? 第 2..M + 1 行:第 i + 1 行,第 i + 1 行 有 N 個整數,表示該位置的狀態: 0 為水; 1 為蓮花; 2 為巖石; 3 為貝茜開始的位置; 4 為貝茜要去的目標位置.

Output

? 第 1 行: 一個整數: 需要添加的最少的蓮花數. 如果無論如何貝茜也無法跳到,輸出 -1.
? 第 2 行: 一個整數: 在添加的蓮花最少基礎上,貝茜從起始點跳到目標點需要的最少的步數。如果第1行輸出-1,這行不輸出。
? 第 3 行: 一個整數: 添加的蓮花的最少數量時,跳躍步數為第2行輸出的值的跳躍路徑的條數 如果第1行輸出-1,這行不輸出。

先用dijkstra求出到達終點所需添加的最少荷葉,再用一次dijkstra求出最短路及最短路條數

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <queue>
 4 #include <cstring>
 5 using namespace std;
 6 typedef pair<int,int> P;
 7 priority_queue<P,vector<P>,greater<P> > que;
 8 int m,n,sx,sy,tx,ty,a,b,ta,tb,p[31
][31],f[31][31],g[31][31],h[31][31],reg[31][31],d[9]={1,2,-1,-2,-1,2,1,-2,1}; 9 void bfs() 10 { 11 while(!que.empty()) 12 { 13 int x=que.top().second;que.pop(); 14 int a=x/100,b=x%100; 15 if (reg[a][b]) continue; 16 reg[a][b]=1; 17 for (int i=0;i<8;i++) 18 { 19 int ta=a+d[i],tb=b+d[i+1]; 20 if (ta>=1&&ta<=m&&tb>=1&&tb<=n&&p[ta][tb]!=2) 21 { 22 if (p[ta][tb]==0&&f[ta][tb]>f[a][b]+1) 23 { 24 f[ta][tb]=f[a][b]+1; 25 que.push(P(f[ta][tb],ta*100+tb)); 26 } 27 if (p[ta][tb]!=0&&f[ta][tb]>f[a][b]) 28 { 29 f[ta][tb]=f[a][b]; 30 que.push(P(f[ta][tb],ta*100+tb)); 31 } 32 } 33 } 34 } 35 } 36 void bfs2() 37 { 38 while(!que.empty()) 39 { 40 int x=que.top().second;que.pop(); 41 int a=x/100,b=x%100; 42 if (reg[a][b]) continue; 43 reg[a][b]=1; 44 for (int i=0;i<8;i++) 45 { 46 int ta=a+d[i],tb=b+d[i+1]; 47 if (ta>=1&&ta<=m&&tb>=1&&tb<=n&&p[ta][tb]!=2) 48 { 49 if ((p[a][b]==0&&f[ta][tb]==f[a][b]-1)|| 50 (p[a][b]!=0&&f[ta][tb]==f[a][b])) 51 { 52 if (g[ta][tb]>g[a][b]+1) 53 { 54 h[ta][tb]=h[a][b]; 55 g[ta][tb]=g[a][b]+1; 56 que.push(P(g[ta][tb],ta*100+tb)); 57 } 58 else if (g[ta][tb]==g[a][b]+1) 59 h[ta][tb]+=h[a][b]; 60 } 61 } 62 } 63 } 64 } 65 int main() 66 { 67 memset(f,0x7f,sizeof(f)); 68 memset(g,0x7f,sizeof(g)); 69 scanf("%d%d",&m,&n); 70 for (int i=1;i<=m;i++) 71 for (int j=1;j<=n;j++) 72 { 73 scanf("%d",&p[i][j]); 74 if (p[i][j]==3) sx=i,sy=j,f[i][j]=0,que.push(P(0,i*100+j)); 75 if (p[i][j]==4) tx=i,ty=j; 76 } 77 bfs(); 78 if (reg[tx][ty]) printf("%d\n",f[tx][ty]);else{printf("-1\n");return 0;} 79 memset(reg,0,sizeof(reg)); 80 g[tx][ty]=0;h[tx][ty]=1;que.push(P(0,tx*100+ty)); 81 bfs2(); 82 printf("%d\n%d",g[sx][sy],h[sx][sy]); 83 }

【最短路】白銀蓮花池