福州Day8之圖論專題
圖的類型:
1.有向圖:只可以從箭頭的一段走到另一端,不可以往回走。
2.無向圖:雙向都可以走
計算機中的存儲方式:
1.鄰接矩陣(存儲空間大,如果範圍大,邊稀疏,浪費就大)
2.鄰接表:無權圖:設置結點指針;有權圖:結點,鄰接點指針;鄰接點,邊權值,下一個鄰接點指針。
有向無環圖
不構成環形(即沒有一條路徑會回到起始點使其構成環形)。
拓撲排序
對於任意兩個節點,例如A可以到B,那麼A一定得在B前面(即B不能再A前面)。
入度:所有指向該點的其它節點的邊數的數量。
出度:該點所有指向其它節點的邊的數量。
當入度爲0時,則對其他點沒有影響,可以排在最前端,刪除節點後只要把改點所有出度對應的點的入度都減去即可。
Ps:vector<數據類型>變量名;(會使程序編寫更加容易。)
最小生成樹
在一個帶權的無向圖裏尋找邊權最小和的路線(必須包括這個圖裏每一個點,非每一條邊)。
1.基於邊的算法(krudkal算法)
便利所有的遍歷,會加上(n-1)條邊,每次加入一邊權最小的邊並要判斷加入邊後是否形成環。判斷兩點是否連通,如果已連通,加入邊則成環。否則,不形成環。
2.基於點的算法(prim算法)
先分成兩個集合,每一次找到一條最小的邊,加入對應的點。
【例題】
判斷最小生成數是不是唯一。
分析:先跑出最小生成樹(兩種方法),每次加上一條邊構成環,再減去環中的一條最長的邊,判斷減去這條邊之後是否與最小生成樹的權值一樣。如果一樣,則方案不是唯一。再用樹上dp實現:每次跑該節點的鄰接點,尋找值最大的。
最短路
1.dijkstra(迪傑斯特拉算法)
與prim算法基本一樣,但是要更新相鄰的dist值。(dist對應的是原點到該點的最
短路,基於點的算法。)
2.spfa算法(對Bellman-ford算法的迭代的改進)
跟dijkstra相像。動態更新dist值的過程。
(以上都是單源最短路。)
3.floyed(弗洛伊德算法)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
三重循環枚舉I,j,k。
【例題】
求S到T地的最短路徑或比路徑長1單位距離的路徑,和滿足條件的路徑條數。
分析:在spfa上進行改進。
分類討論當前的dist值。如果等於最短路,條數增加,如果小於次短路,新值等於最短路,當前值改成次段路(次短路更新);等於次短路,條數增加。其餘同於spfa。最終答案爲最短路路徑條數加上次短路路徑條數。