3.14 BFS

BFS

一步一步搜索,每层的搜到的点都和起始位置距离相等

基本框架

  1. 将初始状态放进队列中

  2. while(队列不空){
    取出队头;
    将队头移出队列;

    	进行判断
    	
    	将新的状态放入队列
    	//注意标记
    

    }
    走迷宫


#include<iostream>
#include<queue> 
#include<algorithm>

using namespace std;

const int N=110;
int n,m;
int map[N][N];
int d[N][N];//用于记录步数,同时可以标记哪些点试过了 

typedef pair <int,int> PII;

queue <PII> q;

int dx[5]={0,0,0,1,-1};
int dy[5]={0,1,-1,0,0};


void bfs(){
	
	q.push({1,1});//放入初始状态
	
	while(!q.empty()){//当q非空 
		 auto t=q.front();//拿出q的第一个元素
		 q.pop();//把队头元素踢出 
		 
		 for(int i=1;i<=4;i++){//遍历所有方向 
		 	int x=t.first+dx[i];
		 	int y=t.second+dy[i];
		 	
		 	if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y]==0&&d[x][y]==0){
		 		d[x][y]=d[t.first][t.second]+1;
				q.push({x,y});
			 }
		 	
		 } 	 
	} 
	
	cout<<d[n][m]<<endl;
	
}


int main(){
	
	cin>>n>>m;
	
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>map[i][j];
			
	bfs();
	
	return 0;
} 

八数码

八数码
在这里插入图片描述

将数组转化为字符串存储

代码给了详细的解释

	
#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<queue>
#include<string>

using namespace std;

const int N=10;

queue <string> q;
unordered_map <string,int> d;

int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1};

string c,s;
string end_s="12345678x";

int bfs(){
	
	q.push(s);	//将初始状态存入
	d.insert({s,0}); //记录矩阵状态和对应的距离(这里是初始化) 
	
	while(!q.empty()){
		//非空 
		auto t=q.front();//拿出这个字符串(矩阵) 
		q.pop();//弹出 
		int distance =d[t];//得到t所需的距离 
		if (t==end_s)
			return distance;  //如果到了结尾直接返回值(距离) 
		
		int k=t.find('x'); //找到x所在的位置
		int x=k/3,y=k%3;   //根据矩阵和字符串的转化,得到字符串所对应的矩阵中元素的位置 
		
		for(int i=1;i<=4;i++){
			int xx=x+dx[i],yy=y+dy[i];//下一步的位置
			if(xx>=0&&xx<3&&yy>=0&&yy<3){
				//如果位置在地图的范围中
				int m=3*xx+yy;//还原其在字符串中的位置 
				swap(t[k],t[m]);//将t中x进行一个移动 
				if(d.count(t)==0){
					//如果更新后的t没有出现在d中过,就是说我们之前从来没有遍历过
					q.push(t);
					d[t]=distance+1;
				} 
				swap(t[k],t[m]);//还原,用于下一个遍历 
			} 
		} 
				
	}		 
	
	return -1;//直到空了都没有,就返回-1 
	
}


int main(){
	
	for(int i=1;i<=9;i++){
		cin>>c;
		s+=c;
	}
	
	cout<<bfs()<<endl; 
	
	return 0;
}
Subtask #1 5ms/2.75MB WA #1 Wrong Answer. 5ms/2.74MB WA #2 Wrong Answer. Subtask #2 139ms/10.61MB AC #3 Accepted, 得分 10. Subtask #3 212ms/12.27MB WA #4 Wrong Answer. Subtask #4 279ms/15.58MB WA #5 Wrong Answer. Subtask #5 229ms/12.21MB WA #6 Wrong Answer. Subtask #6 7ms/2.91MB WA #7 Wrong Answer. 7ms/2.74MB WA #8 Wrong Answer. 7ms/2.75MB WA #9 Wrong Answer. 7ms/2.78MB WA #10 Wrong Answer. 7ms/2.74MB WA #11 Wrong Answer. 7ms/2.75MB WA #12 Wrong Answer. 7ms/2.75MB WA #13 Wrong Answer. 12ms/2.77MB WA #14 Wrong Answer. 16ms/2.92MB WA #15 Wrong Answer. 8ms/2.85MB WA #16 Wrong Answer. Subtask #7 12ms/3.00MB WA #17 Wrong Answer. 12ms/3.10MB WA #18 Wrong Answer. 12ms/3.00MB WA #19 Wrong Answer. 12ms/3.02MB WA #20 Wrong Answer. 12ms/2.98MB WA #21 Wrong Answer. 14ms/3.00MB WA #22 Wrong Answer. 22ms/3.01MB WA #23 Wrong Answer. 56ms/3.10MB WA #24 Wrong Answer. 54ms/3.11MB WA #25 Wrong Answer. 20ms/3.14MB WA #26 Wrong Answer. Subtask #8 168ms/11.67MB WA #27 Wrong Answer. 588ms/16.13MB WA #28 Wrong Answer. 245ms/8.08MB WA #29 Wrong Answer. 590ms/16.70MB WA #30 Wrong Answer.#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> vi; int n, m; ll k; vector<int> adj[100001]; void bfs(int s, vi& dist) { dist.assign(n + 1, -1); queue<int> q; dist[s] = 0; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int v : adj[u]) { if (dist[v] == -1) { dist[v] = dist[u] + 1; q.push(v); } } } } set<ll> get_all_sp_edges(int s, int t, const vi& dist) { set<ll> edges; vector<bool> visited(n + 1, false); queue<int> q; q.push(t); visited[t] = true; while (!q.empty()) { int u = q.front(); q.pop(); for (int v : adj[u]) { if (dist[v] == dist[u] - 1) { // 关键:允许所有前驱 int a = min(u, v), b = max(u, v); ll key = 1LL * a * 1000000 + b; edges.insert(key); if (!visited[v]) { visited[v] = true; q.push(v); } } } } return edges; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while (T--) { cin >> n >> m >> k; for (int i = 1; i <= n; i++) adj[i].clear(); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } int sx1, sy1, sx2, sy2; cin >> sx1 >> sy1 >> sx2 >> sy2; vi da, db, dc, dd; bfs(sx1, da); bfs(sy1, db); bfs(sx2, dc); bfs(sy2, dd); if (da[sy1] == -1 || dc[sy2] == -1) { cout << "-1\n"; continue; } int lenA = da[sy1]; int lenB = dc[sy2]; auto ea = get_all_sp_edges(sx1, sy1, da); auto eb = get_all_sp_edges(sx2, sy2, dc); set<ll> common; for (ll e : ea) if (eb.count(e)) common.insert(e); ll c = common.size(); double total = lenA + lenB; if (c > 0 && k > 0) { total = total - 2.0 * c + (2.0 * c * c) / (c + k); } cout << fixed << setprecision(12) << max(total, 1e-9) << &#39;\n&#39;; } return 0; }
10-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值