POJ 3613 Floyd的思想 矩陣乘法

2021-08-26 07:37:20 字數 1949 閱讀 4119

題目描述抽象來看,是指有乙個有向圖,問乙個點經過n條邊到另乙個點的最短距離(邊可重複走)

為了搞這題...去研究了下矩陣乘法...我不是計算機專業~~又看了下他們的離散數學教材...有乙個例子是說求兩點間經過n條邊到達的方案數..mtrix67的blog的第八題講的也是這個問題....

首先看經過n條邊方案數的這個問題...也就是理解一下這個過程...用乙個鄰接矩陣來存圖...點 ( i , j ) 代表 i 到 j 有多少條路...最初矩陣a的初始化時( i , j ) 為兩點i到j直接的邊數...那麼a1存的實際就是每兩點只經過一條邊到達的方案數...那麼看一下 a^2 也就是 a*a ... 做矩陣乘法時是 mutimtrix [ i ] [ j ] = sum ( mtrix1 [ i ] [ k ] * matrix2 [ k ] [ j ] ) < k=1..點數》 ...那麼就是說列舉所有的中間點(k) sum( a 中i到k點的方案數* a中 k 到 j 的方案數) 很明顯能求出每兩點之間經過兩條邊到達的方案數...也就是說 a^2 就代表綜上...同理可證a^3代表兩點之間經過3條邊到達的方案數...a^k代表兩點之間經過k條邊到達的方案數..

理解了這個例子後再來看這道題...這道題雖然也是經過多少多少條邊兩點到達..但求的是最短距離...求最短距離..又聯想方案數的應該和矩陣有關係..很容易能想到floyd...floyd在求最短路徑時列舉中間點..不斷更新兩點兩點的最短距離...回想一下floyd的更新的方程

if (dist [ i ] [ j ]

這個表示式是不是很酷似矩陣乘法的表示式?多了一層判斷再更新,把乘號變成了加號...

因為題目所給的兩點最多有一條邊...令乙個鄰接矩陣a表示兩兩點的初始關係...也就是題目所給的兩點相連的情況..( i , j ) 是邊的權值...那麼( i , j )顯然是 i 到 j 經過一條邊最短路徑長度...定義乙個矩陣乘法的形式floyd的更新方式的矩陣運算:

pp muti(pp a,pp b)

如果這時把 a=a b=a來做....得到的結果顯然是兩點到達經過兩條邊所需要的最短路徑,運用floyd以及求方案數的思維...為什麼這個很類似floyd的式子求出來的是確定了經過邊數的最短距離?因為這個更新和floyd不同的是更新到乙個新的矩陣上去了而不是直接像floyd的自己更新自己...所以在一更新時...不會出現自己剛更新的值又來繼續更新...並且如果a,b矩陣能分辨知道是兩點間幾條邊的最短距離..顯然得到的h矩陣是經過a(其矩陣表示的經過邊數)+b(其矩陣表示的經過邊數)條邊兩點的最短距離。

這個矩陣運算的方式除了更新,形式上和矩陣乘法時一樣的...所以可以運用矩陣乘法的性質來二分求解...例如如果要求 s 到 e 經過n條邊到達的最短距離~~實際上是求 a 矩陣做n次後 ( s, e )的值...這裡直接就看成乘法來思考..也就是求a^n這個矩陣...明顯的用二分的方法來解決就可以了...mtrix67以及我前一篇文章關於這個方法已經說得很清楚了..

這道題要注意的一點就是雖然點的標號可能是1-1000...但邊最多只有100個...所以點最多也就100來個..所以要把點這裡處理下~~把離散的點壓成從1開始連續的好處理得多...

program:

#include#define maxn 106 #define ok printf("yes %d!!\n",p) #define oo 1000000001 using namespace std; struct pp a,h; struct p1 line[maxn]; int n,t,s,e,i,m,x,y,k,point[1005]; bool had[1005]; pp muti(pp a,pp b) pp find(int p) int main() m=n; n=0; for (i=1;i<=1000;i++) if (had[i]) for (y=1;y<=n;y++) for (x=1;x<=n;x++) a.s[x][y]=oo; for (i=1;i<=t;i++) h=find(m); printf("%d\n",h.s[point[s]][point[e]]); } return 0; }

POJ 3613 Floyd 矩陣快速冪

題意 傳送門 poj 3613 cow relays 題解設從 u uu 出發,到 v vv 的長度為 k kk 的最短路徑為 gk u v g k u v gk u v 修改 flo yd floyd floy d 演算法,則有 g k1 k2 u v min 1 w v gk1 u w gk 2...

Floyd演算法的應用 POJ 2240

該題大意是套匯問題,貨幣根據匯率轉換來套取多餘的錢數,由於是各個貨幣兩兩轉換,即由floyd判環應用變形則可解決問題。floyd演算法用於解決任意兩個節點之間的最短距離,判斷是否成環等,其實質為動態規劃。1 floyd演算法的應用 2 include 3 include 4 include 5usi...

poj 2570 關於floyd的新思考

刷圖論的艱難歷程開始了,這是隨便一翻看到的例題,剛開始沒有一點思路,但一點點順著書看下去,發現這道題的背後,是對於floyd的新思考。就如同看到傳遞閉包所使用的warshall演算法的驚訝,這一題著實讓我覺得驚豔了一把。不廢話,這題是說,鋪設網路,網路中的一些節點是有一部分運營商運營的,然後,給你兩...