日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

迷宫搜索问题最短路_【算法常用模板】总结(更新中)

發布時間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 迷宫搜索问题最短路_【算法常用模板】总结(更新中) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

搜索類

圖類

排序類

并查集

數學類

位運算

Part1 搜索類

bfs 求迷宮問題最短路徑(未驗證)

#include

#include

using namespace std;

//用于遍歷的結構 (可以添加題目所要求的信息)

typedef struct Node{

int x,y;

int step;

}NODE;

const int NUM = 100; //地圖最大范圍,根據要求具體修改

int M,N;

int m[NUM][NUM]; // 地圖數組

int vis[NUM][NUM];

bool check(NODE& node){

int x = node.x;

int y = node.y;

//三種不可訪問情況

if(x < 1 || y < 1 || x > M || y > N ) return 0; //地圖邊界判斷(一定要最先判斷)

if(vis[x][y]) return 0; //是否被訪問過判斷

if(m[x][y] == '*') return 0; //是否是不可訪問的節點判斷(具體題目不同 假設為*)

//可訪問

return 1;

}

//判斷是否是所求的節點

bool checkRight(NODE& node){

if(m[node.x][node.y] == '1') return 1; //假設1為目標

return 0;

}

int mov[4][2]={{0,1},{0,-1},

{1,0},{-1,0}}; //用于移動的數組,這里是四個方向(具體問題具體分析)

NODE bfs(NODE startNode){

//初始化

queue Q;

vis[startNode.x][startNode.y] = 1;

Q.push(startNode);

//正式開始遍歷

while(!Q.empty()){

NODE nowNode = Q.front(); //獲取判斷節點

if(checkRight(nowNode)) return nowNode; //達到目標節點,獲取目標節點

//進行四個方向遍歷(具體問題可能會不同)

for(int i = 0; i < 4; i++){

NODE nextNode;

//下一個位置信息

nextNode.step = nowNode.step + 1;

nextNode.x = nowNode.x + mov[i][0];

nextNode.y = nowNode.y + mov[i][1];

if(check(nextNode)){ //判斷是否可訪問;

vis[nextNode.x][nextNode.y] = 1; //標記為已訪問

Q.push(nextNode);

}

}

}

}

int main(){

cin >> M >> N;

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

for(int j = 1; j <= N; j++)

cin >> m[i][j];

//初始節點(根據題目具體要求位置)

NODE sNode;

sNode.step = 0;

sNode.x = 1;

sNode.y = 1;

NODE targetNode = bfs(sNode);

cout << targetNode.step << endl; //輸出題目要的節點信息

}

dfs

求總的路徑數目

Part2 圖類

最小生成樹 (Prim)

#include

using namespace std;

const int INF = 0x3fffffff;

int vis[N];

void prim(int c[][],int u) {

int i,j;

vis[u] = 1;

for(i = 1; i <= N; i++) {

closet[i] = c[u][i];

}

for(i = 0; i < N; i++){

int t = u;

int min = INF;

int j;

for(j = 1; j <= N; j++){

if(!vis[u] && lowcost[j] < min){

min = closet[j];

t = j;

}

}

if (t == u) break;

for(j = 1; j <= N; j++){

if(!vis[j] && lowcost[j]>c[t][j]){

lowcost[j] = c[t][j];

}

}

}

}

單元最短路 (DJ)

const int MAXINT = 32767;

const int MAXNUM = 10;

int dist[MAXNUM];

int prev[MAXNUM];

int A[MAXUNM][MAXNUM];

void Dijkstra(int v0)

{

bool S[MAXNUM]; // 判斷是否已存入該點到S集合中

int n=MAXNUM;

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

{

dist[i] = A[v0][i];

S[i] = false; // 初始都未用過該點

if(dist[i] == MAXINT)

prev[i] = -1;

else

prev[i] = v0;

}

dist[v0] = 0;

S[v0] = true;

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

{

int mindist = MAXINT;

int u = v0;    // 找出當前未使用的點j的dist[j]最小值

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

if((!S[j]) && dist[j]

{

u = j; // u保存當前鄰接點中距離最小的點的號碼

mindist = dist[j];

}

S[u] = true;

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

if((!S[j]) && A[u][j]

{

if(dist[u] + A[u][j] < dist[j]) //在通過新加入的u點路徑找到離v0點更短的路徑

{

dist[j] = dist[u] + A[u][j]; //更新dist

prev[j] = u; //記錄前驅頂點

}

}

}

}

多源最短路 (Floyd)

typedef struct

{

char vertex[VertexNum]; //頂點表

int edges[VertexNum][VertexNum]; //鄰接矩陣,可看做邊表

int n,e; //圖中當前的頂點數和邊數

}MGraph;

void Floyd(MGraph g)

{

int A[MAXV][MAXV];

int path[MAXV][MAXV];

int i,j,k,n=g.n;

for(i=0;i

for(j=0;j

{

A[i][j]=g.edges[i][j];

path[i][j]=-1;

}

for(k=0;k

{

for(i=0;i

for(j=0;j

if(A[i][j]>(A[i][k]+A[k][j]))

{   A[i][j]=A[i][k]+A[k][j];

path[i][j]=k;

}

} }

Part3 排序類

數組排序 sort

可對任意類型的數組排序。可以自定義排序規則

#include //頭文件

sort(數組名,數組名+數組長度) //自定義排序

sort(數組名,數組名+數組長度,cmp比較規則) //自定義排序

//自定義排序規則

bool cmp(Node& a , Node& b){

if(a.x == b.x) return a.y < b.y;

return a.x < b.x;

}

cmp排序函數的自定義方法:

return true 就是a在b前

return false 就是b在a前

默認排序例子(小到大)

#include

#include

using namespace std;

const int N = 5;

int main(){

int arr[N];

for(int i = 0; i < 5; i++){

cin >> arr[i];

}

sort(arr, arr + N);

for(int i = 0; i < 5; i++){

cout << arr[i] <

}

return 0;

}

自定義排序例子

#include

#include

using namespace std;

typedef struct NODE{

int x,y;

}Node;

//自定義排序規則

bool cmp(Node& a , Node& b){

if(a.x == b.x) return a.y < b.y;

return a.x < b.x;

}

const int N = 5;

int main(){

Node arr[N];

for(int i = 0; i < 5; i++){

cin >> arr[i].x >> arr[i].y;

}

sort(arr, arr + N, cmp); //自定義排序

for(int i = 0; i < 5; i++){

cout << arr[i].x << " " <

}

return 0;

}

優先隊列 priority_queue

用于動態排序的結構(需要不斷的改變排序的元素)

如:哈夫曼樹的構造

#include

priotrity_queue pq //默認定義 從大到小

priotrity_queue,cmp > pq

//自定義排序規則 (有兩種不用自己寫的規則less和greater less和默認一樣從大到小 greater從小到大)

struct cmp {

bool operator() (Node& a , Node& b) {

if (a.x == b.x) return a.y < b.y;

return a.x < b.x;

}

};

//基本方法

pq.push(node) //加入隊列

pq.empty() //隊列是否

pq.top() //獲得隊頭元素(注意和queue的區別,queue是front)

pq.pop() //出隊

注意:true false 對應的方向剛好與sort相反

初步使用

#include

#include

#include

#include

using namespace std;

const int N = 5;

int main(){

priority_queue, greater > pq; //整型從小到大

// priority_queue, less > pq; //整型從大到小 同priority_queue pq;

int x;

for(int i = 0; i < 5; i++){

cin >> x;

pq.push(x);

}

while(!pq.empty()){

cout << pq.top() <

pq.pop();

}

return 0;

}

自定義排序例子

#include

#include

#include

#include

#define Node ElemType

using namespace std;

const int N = 5;

typedef struct NODE{

int x,y;

}Node;

//自定義排序規則

struct cmp {

bool operator() (Node& a , Node& b) {

if (a.x == b.x) return a.y < b.y;

return a.x < b.x;

}

};

int main(){

Node arr[N];

priority_queue, cmp> pq;

for(int i = 0; i < 5; i++){

cin >> arr[i].x >> arr[i].y;

pq.push(arr[i]);

}

while(!pq.empty()){

cout << pq.top().x << " " << pq.top().y <

pq.pop();

}

return 0;

}

Part4 并查集

初始化數組為-1

find(int a); //找老大

union(int a, int b) // a集團加入b集團

不帶路徑壓縮:

int find(int a){

return boss[a]?find(a):a;

}

void union(int a, int b){

int fa = find(a);

int fb = find(b);

boss[a] = b;

}

帶路徑壓縮:

int find(int a){

int bigBoss;

int son = a;

int temp;

while(boss[a]) a = boss[a];

bigBoss = a; //找到大老板

//把路徑上的上司不是大老板的全部直屬大老板

while( son != bigBoss ){

temp = boss[son];

boss[son] = bigBoss;

son = temp;

}

return bigBoss;

}

void union(int a, int b){

int fa = find(a);

int fb = find(b);

boss[a] = b;

}

Part5 數學類

最大公因數(輾轉相除法)

int gcd(int a, int b){

return b>0?gcd(b,a%b):a;

}

最小公倍數

int gcd(int a, int b){

return b>0?gcd(b,a%b):a;

}

int lcm(int a, int b){

return a*b/gcd(a,b);

}

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的迷宫搜索问题最短路_【算法常用模板】总结(更新中)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。