在這一專題裡,首先了解了圖資料結構的一些基礎知識以及圖的儲存方式。
圖的一些基礎知識包括:圖的概念,圖的一些部件的命名,以及一些基本的數量關係
圖的表示形式一般包括:矩陣,鄰接表
我感到最有趣的就是鄰接表的陣列表示形式了,開銷低且高效,感覺甚是神奇,下面貼出鄰接表的陣列表示形式:
struct edge
bf[e];
void addedge(int x, int y, typec c)
基礎知識學習了解之後,又學習了並查集。並查集理解起來很簡單,寫起來也很簡單,但是它的作用很強大。並查集是之後的求最短路的kruskal演算法的基礎。而在求最小生成樹時,我覺得kruskal演算法比prim演算法更容易理解,也更容易實現。下面是kruskal演算法(並查集)的**例項:
#include#include#includeusing namespace std;
const int max=105;
int c[max];
struct xy
dis[max*(max-1)/2];
int find(int i)
void merg(int a,int b)
}bool cmp(xy a,xy b)
for(int i=0;i上述例項是我的此專題的1005的ac**,題目是最經典的「暢通工程」,即用最短的道路連線所有城鎮。可以看到,完全是並查集,只不過最後有乙個排序(貪心),然後選擇邊的過程。很好理解。
另外,通過對並查集實現的循序漸進的一次次優化,我也體會到了思考的樂趣。
學習完了並查集及兩種最小生成樹的幾種經典演算法:prim演算法,kruskal演算法後,又學習了最短路問題的三種演算法:dijkstra演算法(貪心),bellman-ford演算法,spfa演算法(bellman-ford演算法的佇列實現)
三者都應用了鬆弛技術,剛開始學的時候是一臉懵逼啊,怎麼起個這麼奇怪的名字。。。。想明白了其實很好理解,就是用現在的最小路徑去更新其他的路徑。
三種演算法當然有區別了:dijkstra演算法不能用於處理帶有負權值的圖,因為這一演算法對標記過得點就不能進行更新了。有負權值邊時,有可能會使已標記過的點的最短距離變短,但dijkstra演算法就不會進行更新。注意這一點與dijkstra演算法中鬆弛技術的區別。
而bellman-ford演算法,spfa演算法可以實現處理帶負權值的圖,處理的情況更一般些。下面貼出bellman-ford演算法的模板:
#define max_ver_num 10 //頂點個數最大值
#define max 1000000
int edge[max_ver_num][max_ver_num]; //圖的鄰接矩陣
int vexnum; //頂點個數
void bellmanford(int v) //假定圖的鄰接矩陣和頂點個數已經讀進來了}}
} }}
以上就是這學期圖論學習的內容了,看大神的介紹都是很基礎的東西,還是繼續努力,希望能在暑假期間的集訓好好鞏固基礎 專題四總結
圖的定義 很簡單,g v,e v e分別表示點和邊的集合。圖的表示 主要有兩種,鄰接矩陣和鄰接表,前者空間複雜度,o v2 後者為o v e 因此,除非非常稠密的圖 邊非常多 一般後者優越於前者。圖的遍歷 寬度遍歷bfs start 1 佇列q empty,陣列bool visited v q.pu...
專題四總結
專題四總結 專題四圖演算法,到目前為止學習了並查集,最小生成樹,最短路。並查集找父節點 int find int x 練習四1003 另一種 int find int a 練習四1022 最小生成樹只會用kruscul 演算法,用這乙個能做不少題了也就懶得學 primer.double kru re...
4專題四總結
專題四主要就是最短路徑問題。一般最短路徑有兩種演算法prim與kruscal演算法,然而這兩種演算法核心技術就是並查集。並查集。即 不相交集合 將編號分別為1 n的n個物件劃分 為不相交集合,在每個集合中,選擇其中某個元素代表所在集合。常見兩種操作 合併兩個集合查詢某元素屬於哪個集合 模板演算法 v...