圖的遍歷(深搜和廣搜的思想)
阿新 • • 發佈:2019-01-21
一、深度優先搜尋遍歷圖
1、圖的儲存:二維陣列,i,j表示點,a[i][j]表示邊長。
//圖的dfs遍歷 #include<bits/stdc++.h> using namespace std; const int INF=0x3ffffff; int n,m,sum; int a[101][101],vis[101]; void dfs(int st) { int i; printf("%d ",st); sum++; if(sum==n) return ; //訪問次數達到要求,結束。 for(i=1;i<=n;i++) { if(vis[i]==0&&a[st][i]==1) //訪問未訪問的節點 { vis[i]=1; //每次標記找過的節點 dfs(i); //遞迴查詢。 } } return ; } int main(void) { int i,j; int v,u; memset(vis,0,sizeof(vis)); scanf("%d %d",&n,&m); for(i=1;i<=n;i++) //初始化 { for(j=1;j<=n;j++) if(i==j) a[i][j]=0; else a[i][j]=INF; } while(m--) { scanf("%d %d",&v,&u); //二維陣列儲存 a[v][u]=1; a[u][v]=1; } sum=1; vis[1]=1; dfs(1); return 0; } /*測試樣例 5 5 1 2 1 3 1 5 2 4 3 5 結果輸出: 1 2 4 3 5 */
二、廣度優先搜尋的圖的遍歷
相當於二叉樹的層序遍歷,就是一一個點為中心,遍歷他周圍的節點。
//圖的bfs遍歷 #include<bits/stdc++.h> using namespace std; const int INF=0x3fffff; int a[101][101],vis[101]; //二維陣列儲存結構和vis標記 int q[101]; //相當於佇列,儲存資料。 int main(void) { int n,m,i,j; int u,v; memset(vis,0,sizeof(vis)); //初始化標記陣列 scanf("%d %d",&n,&m); for(i=1;i<=n;i++) //初始胡二維陣列 { for(j=1;j<=n;j++) if(i==j) a[i][j]=0; else a[i][j]=INF; } while(m--) { scanf("%d %d",&u,&v); //輸入無向圖 a[v][u]=1; a[u][v]=1; } //初始胡佇列 memset(q,0,sizeof(q)); int head=1,tail=1,tp,sum=0; q[tail]=1; tail++; vis[1]=1; while(head<tail) { tp=q[head]; for(i=1;i<=n;i++) { if(vis[i]==0&&a[tp][i]==1) //將未走過的節點進隊。 { vis[i]=1; q[tail]=i; tail++; } if(tail>n) //結束條件。 break; } head++; } for(i=1;i<tail;i++) //遍歷輸出 printf("%d ",q[i]); return 0; } /* 輸入樣例: 5 5 1 2 1 3 1 5 2 4 3 5 輸出樣例: 1 2 3 5 4 */
三、例題
計算出城市地圖的最短路徑。
//城市地圖(圖的深度優先遍歷) #include<bits/stdc++.h> using namespace std; int a[101][101],vis[101]; //二維陣列,標記陣列 int mi,n,m; //最小值 const int INF=0xffff; void dfs(int tp,int dis) { if(dis>mi) return ; //如果路徑大於原路徑就返回 if(tp==n) //找到終點 { if(dis<mi) mi=dis; return ; } for(int i=1;i<=n;i++) { if(a[tp][i]!=INF&&vis[i]==0) //未標記過的路徑 { vis[i]=1; dfs(i,dis+a[tp][i]); vis[i]=0; } } return ; } int main(void) { int i,j; scanf("%d %d",&n,&m); for(i=1;i<=n;i++) //二維陣列初始化 { for(j=1;j<=n;j++) if(i==j) a[i][j]=0; else a[i][j]=INF; } int u,v,w; while(m--) { scanf("%d %d %d",&u,&v,&w); a[u][v]=w; } mi=INF; dfs(1,0); printf("%d\n",mi); //輸出最短路徑的結果。 return 0; } /*輸入樣例: 5 8 1 2 2 1 5 10 2 3 3 2 5 7 3 1 4 3 4 4 4 5 5 5 3 3 輸出樣例: 9 */