沒有用的話qaq :
Ummmm...圖論的大部分知識本來早就有學過,只是一直沒有寫成博文來梳理,但既然上了qbxt DP圖論就寫一篇來總結下,主要是來聽DP的,但...由於太菜的原因,DP聽得天花亂墜QWQ **
一,圖:圖是邊和點組成的幾何體 G=< V , E > V是點集合,E是邊集
形如這樣的東西就是一個圖
二,圖的相關基本概念
1,邊:圖上連接點和點之間的東西叫做邊,圖上邊分為有向邊和無向邊。有向邊是有方向的邊,無向邊是沒有方向的邊,在圖上具體體現為有無箭頭。
2,點:圖上的點
3,權:就是某個東西的大小,圖中一般會存在點權和邊權,就是給點賦一個值和給邊賦一個值,沒有權的情況稱為無權,權值為負的時候稱為負權(注意以后算法中的負權邊)
4,環:無向邊中的環就像上圖中的1,2,5和2,3,4,5,環的特點是,環上任意一點能到達通過環能回到自己!!有向圖的環相同,就是一個點如果能通過一條路徑回到自己,我們就說這條路徑是一個環,負環的定義為環上所有邊權之和小於零。
5,重邊:即兩個點之間有重復的邊,但注意兩個點之間重復但方向不同的邊不屬於重邊。
6,有向無環圖(DAG):字面意思,是有向圖且沒有環的圖稱為有向無環圖,簡稱DAG,一般與有向圖縮點后拓撲排序后,DAG上的DP有關,同時DP的實質是個DAG。
7,路徑:從一條邊到另一條邊的路稱為路徑,簡單路徑是一條沒有環的路徑。
8,連通:如果一個點A能到達另一個點B,稱為點A和點B連通,如果點B也能到達A點則稱點A和點B是強連通的,從圖中某一點出發,如果能到達圖上任意一點,則稱,這個圖是一個連通圖。
三,特殊的圖
1,樹:樹是一種特殊的圖
2,完全圖:圖上任意兩點之間都有一條無向邊的圖
3,競賽圖:與完全圖長得完全一致,不過競賽圖上的邊有方向
4,基環樹:有一個環,這個環向四周發散的全是樹,這種圖叫做基環樹。
5,仙人掌圖:每條邊至多在一個環上的圖
四,圖的存儲方式
圖的存儲存的都是有向邊,對於無向邊的情況,我們將其拆成兩條有向邊存儲。
1,鄰接矩陣
鄰接矩陣因為比較耗內存O( n^2 ),且遍歷較慢的原因,在OI中並不常用,因為博主比較弱,博主認為只有floyd會用的這個怪怪的東西。
鄰接矩陣就是一個二維數組,二維數組就是矩陣嘛,一開始我們要對鄰接矩陣進行初始化,可能置成0,可能置成-1,也可能置成正無窮,無論置成什么,都代表沒有邊(即如果 g[a][b]=初始化的值則代表a到b之間沒有邊)。
加邊的話也很簡單,就是如果是s到e存在一條邊權為d的邊,那么g[s][e]=d,同時要注意某些題目有重邊的情況,以防需要留下的邊權被不需要留下的沖刷掉,一般我們會留下邊權最小的邊或者邊權最大的邊,留下的方法就是加個if判斷一下。
鄰接矩陣的有點是可以快速知道s到e之間有沒有邊,邊權是多少,缺點是遍歷時間復雜度較高,同時,定義較浪費空間(因為有很多節點之間沒有邊)。
2,鄰接表
比起鄰接矩陣,鄰接表是OI中最常用的存圖方法
其原理是用了n個鏈表,用一個first數組在存邊的時候將從某節點出發的所有邊串了起來。
struct node
{
int ed,len,nxt;
};
node edge[2333];
int first[2333],cnt;
inline void add_edge(int s,int e,int d)
{
cnt++;
edge[cnt].ed=e;
edge[cnt].len=d;
edge[cnt].nxt=first[s];
first[s]=cnt;
return;
}//加邊
int main()
{
scanf("%d%d%d",&s,&e,&d);
add_edge(s,e,d);
//add_edge(e,s,d); 若是無向邊
}
for(int i=first[s];i;i=edge[i].ed)
{
}//遍歷從s出發的所有邊
寫在最后 Yousiki Orz