双向广搜字符串最短距离最短
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<sstream>
#include<string>
#include<bitset>
#include<utility>
#include<numeric>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const LL LINF = (1LL <<62);
const int INF = 1 << 30;
const int NS = 500010;
const int MS = 19;
const int MOD = 1000000007;
const double PI = acos(-1.0);
#define form(_i, L, R) for (int (_i) = L; (i) <= (R); ++(_i))
inline bool isdigit(char ch){return ((ch<='9')and(ch>='0'));}
inline void read(int &x){
char ch;
bool flag=false;
for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') flag=true;
for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
x=flag?-x:x;
}
#ifndef ONLINE_JUDGE
typedef set<string> StringSet;
#endif
#ifdef ONLINE_JUDGE
typedef unordered_set<string> StringSet;
#endif
struct Node;
typedef bool (*NodeCmper) (Node*, Node*);
typedef set<Node *, NodeCmper> NodeSet;
typedef vector<string> VString;
struct Node{
string word;
vector<Node *> parents;
Node(){}
Node(string _word){
word = _word;
parents.clear();
}
bool operator < (const Node& cmp){
return ((this->word) < (cmp.word));
}
void addParents(Node *cur)
{
parents.push_back(cur);
}
vector<VString *>* getPath()
{
vector<VString *> *paths = new vector<VString *>;
if(!parents.empty())
{
vector<VString *> *pre;
for(__typeof(parents.begin()) it = parents.begin(); it != parents.end(); it++)
{
pre = (*it)->getPath();
for(__typeof(pre->begin()) itr = pre->begin(); itr != pre->end(); itr++)
{
(*itr)->push_back(word);
}
paths->insert(paths->end(), pre->begin(), pre->end());
}
}
else
{
VString *cur = new VString(1, word);
paths->push_back(cur);
}
return (paths);
}
void findNext(NodeSet *nexts, NodeSet *tail, vector<VString>& ans, bool isLeft, StringSet &words)
{
string cur = word;
int len = cur.length();
for(int i = 0; i < len; i++)
{
char reChar = cur[i];
for(char ch = 'a'; ch <= 'z'; ch++)
{
if(ch == reChar) continue;
cur[i] = ch;
if(words.find(cur) != words.end())
{
Node* next = new Node(cur);
checkMatch(next, nexts, tail, ans, isLeft);
}
}
cur[i] = reChar;
}
return ;
}
void checkMatch(Node* next, NodeSet *nexts, NodeSet *tail, vector<VString>& ans, bool isLeft)
{
__typeof(tail->begin()) it = tail->find(next);
if(it != tail->end())
{
vector<VString *> *tPath, *hPath;
hPath = this->getPath();
tPath = (*it)->getPath();
if(!isLeft) swap(hPath, tPath);
__typeof(hPath->begin()) pH, pT;
for(pH = hPath->begin(); pH != hPath->end(); pH++)
{
for(pT = tPath->begin(); pT != tPath->end(); pT++)
{
ans.push_back(*(*pH));
ans.back().insert(ans.back().end(), (*pT)->rbegin(), (*pT)->rend());
}
}
}
else if(ans.empty())
{
__typeof(nexts->begin()) itr = nexts->find(next);
if(itr != nexts->end())
{
(*itr)->addParents(this);
}
else
{
next->addParents(this);
nexts->insert(next);
}
}
}
};
bool nodeCmp(Node* pa, Node* pb)
{
return pa->word < pb->word;
}
class Solution {
public:
vector<VString> findLadders(string begins, string ends, StringSet &words) {
vector<VString> ans;
if(begins == ends)
{
ans.push_back(VString(2, begins));
}
words.insert(ends);//防止begins可以一次转换到ends的情况
Node pHead = Node(begins), pTail = Node(ends);
NodeSet *head = new NodeSet(nodeCmp), *tail = new NodeSet(nodeCmp), *nexts = new NodeSet(nodeCmp);
head->insert(&pHead), tail->insert(&pTail);
bool isLeft = true;
int circle = 0;
while(ans.empty() && head->size() && tail->size())
{
circle++;
if( head->size() > tail->size() )
{
swap(head, tail);
isLeft = !isLeft;
}
nexts->clear();
for(__typeof(head->begin()) it = head->begin(); it != head->end(); it++)
{
words.erase((*it)->word);
}
for(__typeof(head->begin()) it = head->begin(); it != head->end(); it++)
{
(*it)->findNext(nexts, tail, ans, isLeft, words);
}
swap(head, nexts);
}
return ans;
}
};
char s[101010];
int main()
{
#ifndef ONLINE_JUDGE
freopen("ladderLength.in", "r", stdin);
freopen("ladderLength2.out", "w", stdout);
#endif
set<string> words;
string bW, eW, wo;
cin>>bW>>eW;
bW = bW.substr(1, bW.size() - 2);
eW = eW.substr(1, eW.size() - 2);
scanf("%s", s);
cout<<"bW = "<<bW<<" eW = "<<eW<<endl;//<<wo<<endl;
const char *d = ",[]\"";
char *p;
p = strtok(s,d);
int cnt = 0;
while(p)
{
printf("%s\n",p);
words.insert(string(p));
if(cnt > 5000)
{
break;
}
p=strtok(NULL,d);
cnt++;
}
printf("words.size = %d\n", (int)words.size());
Solution sol;
vector<VString> ans = sol.findLadders(bW, eW, words);
printf("cnt = %d ans = %d\n", cnt, ans.size());
int sz = ans.size();
for(int i = 0; i < sz; i++)
{
VString cur = ans[i];
int len = cur.size();
for(int j = 0; j < len; j++)
{
cout<<cur[j]<<"->";
}
cout<<"NULL"<<endl;
}
return 0;
}
// __typeof(val.begin()) it = val.begin();
//ios::sync_with_stdio(false);cout<<setprecision(30);