TT的魔法貓(最短路優化Floyd弗洛伊德演算法)

2021-10-23 03:45:28 字數 1969 閱讀 2608

眾所周知,tt 有乙隻魔法貓。

這一天,tt 正在專心致志地玩《貓和老鼠》遊戲,然而比賽還沒開始,聰明的魔法貓便告訴了 tt 比賽的最終結果。tt 非常詫異,不僅詫異於他的小貓咪居然會說話,更詫異於這可愛的小不點為何有如此魔力?

魔法貓告訴 tt,它其實擁有一張遊戲勝負表,上面有 n 個人以及 m 個勝負關係,每個勝負關係為 a b,表示 a 能勝過 b,且勝負關係具有傳遞性。即 a 勝過 b,b 勝過 c,則 a 也能勝過 c。

tt 不相信他的小貓咪什麼比賽都能**,因此他想知道有多少對選手的勝負無法預先得知,你能幫幫他嗎?

第一行給出資料組數。

每組資料第一行給出 n 和 m(n , m <= 500)。

接下來 m 行,每行給出 a b,表示 a 可以勝過 b。

對於每一組資料,判斷有多少場比賽的勝負不能預先得知。注意 (a, b) 與 (b, a) 等價,即每乙個二元組只被計算一次。

33 3

1 21 3

2 33 2

1 22 3

4 21 2

3 4004

• 由 1 ≤ ?, ? ≤ 500 資料規模可以得知本題要求複雜度為?(?3)。

• 因為勝負關係具有傳遞性,因此可以用 floyd 演算法求出任意兩點的勝負關係(傳遞閉包),即可求出答案

?[a,b] = 1表示 a 比 b 強

d[a,b] = 0表示 a 與 b 的勝負關係不明

?[a,b] = 0 且 ?[a,b] = 0即表示 a 與 b 的勝負關係無法預先判斷

floyd演算法介紹

• floyd–warshall 演算法應用

• 用於求取圖中任意兩點之間的關係

• 多源最短路,任意兩點的距離關係

• 圖上的傳遞閉包,任意兩點的連通關係

• 複雜度 ?(?3)

• floyd–warshall 演算法實現

void

floyd

(int n,

int*

*d)

tt的魔法貓只需將d[i][j] = min( d[i][j], d[i][k] + d[k][j] ) 改為 d[i][j] = max( d[i][j], d[i][k] & d[k][j] ),即d[i][j] = d[i][j] || ( d[i][k] & d[k][j] )

如果只是裸的floyd會超時,我們可以根據題目特點進行優化,發現:當d[i][k] = 0時,沒有必要進行第三層迴圈,因為此時d[i][k] & d[k][j] 一定等於0.

#include

int d[

510]

[510];

intmain()

for(

int k=

1;k<=n;k++

)for

(int i=

1;i<=n;i++)if

(d[i]

[k]!=0)

//剪枝,進行優化。d[i][k]=0則不再進行下層迴圈

for(

int j=

1;j<=n;j++

) d[i]

[j]=d[i]

[j]||

(d[i]

[k]&d[k]

[j])

;for

(int i=

1;i<=n;i++

)for

(int j=

1;j(d[i]

[j]||d[j]

[i])

//不能判斷勝負關係

ans--

;printf

("%d\n"

,ans);}

return0;

}

TT的魔法貓 Floyd演算法

題目 眾所周知,tt 有乙隻魔法貓。這一天,tt 正在專心致志地玩 貓和老鼠 遊戲,然而比賽還沒開始,聰明的魔法貓便告訴了 tt 比賽的最終結果。tt 非常詫異,不僅詫異於他的小貓咪居然會說話,更詫異於這可愛的小不點為何有如此魔力?魔法貓告訴 tt,它其實擁有一張遊戲勝負表,上面有 n 個人以及 m...

Week7 TT 的魔法貓 弗洛伊德演算法

題目描述 眾所周知,tt 有乙隻魔法貓。這一天,tt 正在專心致志地玩 貓和老鼠 遊戲,然而比賽還沒開始,聰明的魔法貓便告訴了 tt 比賽的最終結果。tt 非常詫異,不僅詫異於他的小貓咪居然會說話,更詫異於這可愛的小不點為何有如此魔力?魔法貓告訴 tt,它其實擁有一張遊戲勝負表,上面有 n 個人以及...

Vijos 佳佳的魔法藥水 最短路

發完了k張 佳佳卻得到了乙個壞訊息 他的mm得病了!佳佳和大家一樣焦急萬分!治好mm的病只有一種辦法,那就是傳說中的0號藥水 怎麼樣才能得到0號藥水呢?你要知道佳佳的家境也不是很好,成本得足夠低才行 得到一種藥水有兩種方法 可以按照魔法書上的指導自己配置,也可以到魔法商店裡去買 那裡對於每種藥水都有...