状态转移BFS+最短路【洛谷P1032】

题目链接戳这里!!!https://www.luogu.org/problemnew/show/P1032

拿到这个题目的时候真的是一脸懵逼的,这种抽象的,朦胧的最短路还是很难的,(大概只有我觉得难吧)。

前前后后大概做了三个小时的时间,AC的那一刻兴奋拿给队友@TDD,让他做一下,结果他10分钟就码完了???!!!,跑的DFS,T了一个数据点。

求最短路还是用BFS啊!

首先这个题目,有一定的模拟性,需要对字符串不断的操作改动。没有用rope尝试,不知道会不会快。

思路:

对于每一个字符串,记录一个stp表示步数。由此可得,如果有哪一个字符串最先变成给定的字符串,那么步数一定是最少的(显然成立)。所以BFS显然可以很清晰的写出来。直接这么做可能会T。我们用map记录一下出现过的字符,把重复构造的去掉,那么就可以愉快的AC啦!

#include <bits/stdc++.h>
using namespace std;
struct node
{
	string str;
	int stp;
};
string a,b;
multimap<string,string> mp;
map<string,bool> vis;
bool bfs(string s)
{
	queue<node> q;
	q.push(node{s,0});
	vis[s] = 1;
	while(!q.empty())
	{
		node tmp = q.front();
		q.pop();
		string now;
		if(tmp.stp>10)
		{
			return false;
		}
//		if(tmp.str==b)
//		{
//			cout<<tmp.stp<<endl;
//			return true;
//		}
		for(auto it = mp.begin();it!=mp.end();++it)
		{
			for(int i=0;i<tmp.str.size();i++)
			{
				if(tmp.str.substr(i,(it->first).size())==it->first)
				{
					now = tmp.str;
					now.replace(i,(it->first).size(),it->second);
					if(now==b)
					{
						cout<<tmp.stp+1<<endl;
						return true;
					}
					if(!vis[now])
					{
						vis[now] = 1;
						q.push(node{now,tmp.stp+1});
					}
					
				}
			}
		}
	}
}
int main()
{
	cin>>a>>b;
	string ta,tb;
	while(cin>>ta>>tb)
	{
		mp.insert(make_pair(ta,tb));
	}
	if(!bfs(a))
	{
		cout<<"NO ANSWER!"<<endl;
	}
	return 0;
} 

题目的思考难度不大,但是对于实现有一定的要求。

猜你喜欢

转载自blog.csdn.net/KIKO_caoyue/article/details/83153935
今日推荐