圖中點的層次(bfs)
阿新 • • 發佈:2022-03-13
回顧一下寬搜的板子:
上一下走迷宮的程式碼,對照一下這個板子,一目瞭然
#include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; typedef pair<int,int> PAII; const int N=200; int g[N][N],d[N][N];//g存的是地圖,d代表到起點所搜尋的距離 int n,m; int bfs() { queue<PAII> q;//用佇列來實現寬搜的操作memset(d,-1,sizeof(d));//所有的點都沒有被搜過,就都賦值為-1 q.push({0,0});//從0開始; d[0][0]=0;//初始化 while(q.size())// { auto t=q.front(); q.pop(); int dx[4]={-1,1,0,0};//實現上下左右遍歷 int dy[4]={0,0,1,-1}; for(int i=0;i<4;i++) { int x=t.first+dx[i],y=t.second+dy[i];//遍歷到新的點左邊 if(x>=0&&y>=0&&x<n&&y<m&&d[x][y]==-1&&g[x][y]==0) { d[x][y]=d[t.first][t.second]+1;//序號+1 q.push({x,y});//把新的遍歷且符合要求的點存入佇列 } } } return d[n-1][m-1]; } intmain(){ cin>>n>>m; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>g[i][j]; cout<<bfs()<<endl; return 0; }
圖中點的層次:
給定一個 nn 個點 mm 條邊的有向圖,圖中可能存在重邊和自環。
所有邊的長度都是 11,點的編號為 1∼n1∼n。
請你求出 11 號點到 nn 號點的最短距離,如果從 11 號點無法走到 nn 號點,輸出 −1−1。
輸入格式
第一行包含兩個整數 nn 和 mm。
接下來 mm 行,每行包含兩個整數 aa 和 bb,表示存在一條從 aa 走到 bb 的長度為 11 的邊。
輸出格式
輸出一個整數,表示 11 號點到 nn 號點的最短距離。
資料範圍
1≤n,m≤1051≤n,m≤105
輸入樣例:
4 5
1 2
2 3
3 4
1 3
1 4
輸出樣例:
1
因為邊權是1,可以使用寬搜來求最短路
第一次搜到的點,就是起點到這個點的最短距離
#include<iostream> #include<cstring> #include<queue> using namespace std; const int N=1e5+10; int h[N],e[N],ne[N],idx; int d[N]; int n,m; void add(int a,int b) { e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } int bfs(){ memset(d,-1,sizeof(d));//初始化 queue<int> q;//佇列裡面儲存的是結點 d[1]=0;//結點到起點的距離 q.push(1); while(q.size()) { int x=q.front(); q.pop(); for(int i=h[x];i!=-1;i=ne[i]) { int j=e[i]; if(d[j]==-1)//沒有被標記過 { d[j]=d[x]+1;//d[j]是沒有標記過的,可以就直接d[x]+1 q.push(j); } } } return d[n]; } int main(){ cin>>n>>m; memset(h,-1,sizeof(h)); while(m--) { int a,b; cin>>a>>b; add(a,b); } cout<<bfs()<<endl; return 0; }