ACM暑期集訓5

2021-08-21 18:41:03 字數 2364 閱讀 8789

今天主要學習力圖論基礎和最短路徑

1.圖論基礎

1)鄰接矩陣存圖

w[i][j]表示以ij為頂點的邊的權值

const int n=105, inf=9999999;

int dis[n], w[n][n],vis[n],n,m;

//鄰接矩陣存圖

for(int i=1; i<=n; ++i)

for(int i=0; i2)鄰接表存圖

直接上模板

int head[maxn]; //head[i]表示i所連的第一條邊的編號(最後輸入的邊的編號)

struct node

e[maxn]; //e[i]表示第i條邊

//加邊:新加了一條a到b權值為w的邊,其下標為cnt( cnt是對邊計數)

void(int a,int b,int w)

遍歷與節點a相連的所有的邊:

for(int i = head[a] ; i != -1 ; i = e[i].next){}

3)圖的遍歷

void dfs(int u)

}}void bfs(int s)

} }

}

2.最短路徑

1)floyd演算法

鬆弛所有可鬆弛的路徑,列舉路徑的起止點和中間點

void floyd()}}

}

接下來上題

每條邊上有乙個權值,從a到b找一條路,使得它在所有路徑中,邊權最大的邊的權值最小。求這個最小的權值。

for(int k=1;k<=n;k++)    

}每個城市有乙個危險值,求從城市a到b,路徑上所經過的其他城市危險值不超過x的最短路長度。

dis[k][i][j] -- 從i到j經過危險值前k小的城市的最短路徑長度

2).dijkstra演算法

分析:將所有的點分為兩部分,已標記的和未標記的

標記之後指的是儲存的路徑已經是最短路徑。

vis[i]-標記節點i    dis[i]-起點到點i的最短距離

初始化:除起點之外dis設為inf

(1)在所有尚未標記的點中選出距離起點最近的點,標記這個點,並且在未標記的點中更新與這個點相鄰的點的最短距離。

(2)重複步驟(1)直到所有的點都被標記,即所有的點儲存的距離都是最短距離。

void dijkstra(int s)

}}

最短路計數    求num[i]:起點到i的最短路條數

if(dis[j]>dis[k]+map[k][j])

num[j]=num[k];

else if(dis[j]==dis[k]+map[k][j])

num[j]+=num[k];

城市之間的路徑各自有高度限制,求從起點到終點允許的最大高度,並求這時的最短距離。

思路:二分查詢滿足條件的最大高度 ,每次求最短路

3)bellman-ford演算法

如果存在權值為負值的邊,dijkstra演算法就會失效。

解決這個問題的方法:bellman-ford演算法  

演算法步驟:

(1)初始化(起點處dis[s]=0,其餘點為inf)

(2)迴圈n-1次(n為點的數目),每次遍歷所有的邊,進行鬆弛操作(對於權值為w的邊,看是否有dis[v]>dis[u]+w)

【一條路徑最多經過n-1條邊,每次迴圈可以保證至少鬆弛一層】

(3)再遍歷一次所有的邊,嘗試進行鬆弛,如果仍然能進行鬆弛(存在dis[v]>dis[u]+w),則說明存在原點可達的負環

struct node

e[maxn];

bool bellman_ford(int s)

}for(int i=0;idis[u]+e[j].w)

return false;

}return true;

}

4)spfa演算法

演算法步驟:

(1)初始化:建立乙個佇列(queue),只將起點放入佇列中          

dis除起點外都為inf,vis除起點外都為0

(2)從佇列中彈出乙個點,鬆弛所有與它直接相連能夠鬆弛的點。如果鬆弛的點不在佇列中,就將其壓入佇列。

(3)重複步驟(2)直到隊列為空。

判斷負環:如果存在節點入隊的次數超過n次,那麼就存在源點可達的負環。

void spfa(int s)}}

}}

貨物在n個城市中(n<=100000)有不同的**,同時在城市之間移動也有一定的花費。現在要在一座城市買一件貨物,在另一座城市賣出去,問最多能夠賺多少錢。

思路:建立乙個源點和乙個匯點

ACM暑期集訓2

今天主要學習了線性dp和揹包問題以及快速冪。1.整數快速冪 這個直接粘上 int qpow int x,int n res res res n n 1 return ans 2.矩陣快速冪 主要就是將整數快速冪的乘法運算換做矩陣的乘法 下面的 是方陣的快速冪 const int n 10 int t...

ACM暑期集訓4

今天主要學習了線段樹,樹狀陣列,st表,差分,分塊和樹剖 好吧,這個已經沒聽懂了 1.線段樹 線段樹涉及許多應用和思想,以下是今天所學 線段樹主要用於處理一段連續區間的插入,查詢,統計,查詢等操作。複雜度 設區間長度是n,所有操作的複雜度是logn級別。性質 線段樹是平衡的2叉樹,最大深度logn ...

ACM暑期集訓12

今天學了字尾陣列,感覺好難理解,只能搬ppt,粘模板了 1 字尾 suffix i 為從下標i開始的字尾 string abcdef suffix 1 bcdef suffix 2 cdef 什麼是字尾陣列?把乙個字串的所有字尾按字典序進行排序。字尾陣列sa i 表示排名為i的字尾下標是什麼,rk ...