FYN 演算法學習1

2021-08-08 16:57:11 字數 1650 閱讀 5640

1. 這是求最小環的模板題

2. 這是輸出路徑的模板題

由於都是模板題,題意就不再贅述,直接從演算法講起~

floyd演算法是通過類似動態規劃的方法求解最短路徑問題的高效演算法,對於正權值和負權值(不含負環)都有效.該演算法主要分為兩步:第一步初始化,對於從u到v的邊,用鄰接矩陣mp[u][v]儲存路徑的權值,若無這條邊則為無窮大(實際寫時定成比較大的數即可),第二步狀態轉移,對於每一對點u,v,列舉是否有點w使得u->w->v的最短路徑比u->v的最短路徑小,如果是則更新它.

核心的狀態轉移**如下:

mp[i][j] = min( mp[i][j], mp[i][k]+mp[k][j] );
floyd法已求得了到最外層迴圈k時,所有點對間以點1,2,……,k-1為中間點的最短路徑.對於每乙個環,這個環可以看為最大編號的點c與其相鄰的兩個點 a 和b 與 a 到 b 的最短路上的點.因此可以用floyd法拓展.

下面是完整**:

#include

using

namespace

std;

typedef

long

long

int ll;

const ll inf=1e9;

const ll maxn=110;

ll mp[maxn][maxn],dis[maxn][maxn];

ll n,m,u,v,len,mincost,temp,num,s;

void init()

}for(int i=1; i<=m; i++)

}void floyd() }}

}}int main()

我們用乙個road陣列儲存輸出的最小路徑,在每次更新最小環的值時更新這一陣列,從開始的點s不斷向前推即可.

cnt=0;

s=j;

while(s!=i)

road[cnt++]=i;

road[cnt++]=k;

這就是最小環路徑的記錄部分,注意p陣列的初始化,將p[i][j]初始化為i,p[i][j]表示從i到j的路徑中經過的第乙個點.

下面是完整**:

#include

#include

using

namespace

std;

typedef

long

long

int ll;

const

int inf=1e6;

const

int maxn=110;

int mp[maxn][maxn],dis[maxn][maxn],road[maxn],p[maxn][maxn];

int n,m,u,v,len,mincost,temp,cnt,s;

void init()

}for(int i=1; i<=m; i++)

}void floyd()

road[cnt++]=i;

road[cnt++]=k;}}

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

}}int main()

}return

0;}

演算法學習 1

插入排序是學習演算法時最先學到的乙個演算法,很簡單,也許看一遍就會理解,從而覺得自己掌握這個基本的演算法。但是很多人可能會像我一樣,過了一段時間,提筆來寫一下插入排序的偽 就很難寫出書本上如此優雅的偽 insertion sort a for j 2 to a.length key a j inse...

演算法學習 1

劍指offer演算法題 題目描述 給你一根長度為n的繩子,請把繩子剪成整數長的m段 m n都是整數,n 1並且m 1,m n 每段繩子的長度記為k 1 k m 請問k 1 x xk m 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到的最大乘積是18。...

演算法學習1

求最大子列和問題 給定n個整數的序列,求最大連續子列和,演算法 求出每乙個子列的和 然後得到最大的和返回 static intmaxsum1 int arr if maxsumreturn maxsum 時間複雜度 t n 3 空間複雜度 o 1 優化1 已經計算過的子列和不需要重複計算,再已經計算...