#include<iostream>
#include<vector>
#include<list>
#include<unordered_map>
#include<unordered_set>
#include <string>
#include<functional>
#include<string.h>
#include<queue>
using namespace std;
class Edge;
class Node ///<節點
{
public:
string value;//權值
int in;//入度
int out;//出度
list<Edge> edge;//出的邊
list<Node> nextnode;//出的邊連的節點
Node(string valuee)
{
value = valuee;
in = 0;
out = 0;
}
};
class Edge ///<邊
{
public:
string weight;//權重
Node *from;//有向圖的起點
Node *to;//有向圖的終點
int num;
Edge(string weightt, Node *fromm, Node *too)
{
weight = weightt;
from = fromm;
to = too;
num = -1;
}
};
struct func //hash 函數
{
size_t operator()(const Edge a) const
{
return ((hash<string>()(a.weight)
^ (hash<Node*>()(a.from) << 1)) >> 1)
^ (hash<Node*>()(a.to) << 1);
}
};
struct cmp_fun //比較函數 ==
{
bool operator()(const Edge &a, const Edge &b) const
{
return memcmp(&a, &b, sizeof(a)) == 0 ? true:false;
}
};
class Graph//完整的圖結構
{
public:
unordered_map<string, Node>node;
unordered_set<Edge, func,cmp_fun>edge;
};
Graph graph;
void ReadGraph(vector<vector<string>>a)//讀圖程序
{
int n = a.size();
for (int i = 0; i<n; ++i)
{
string weight = a[i][0];
string from = a[i][1];
string to = a[i][2];
///<下面兩行代碼過後不管from和to是否出現過就都有了
if (graph.node.find(from) == graph.node.end())//如果from點從沒在哈希中出現過就加入
graph.node.insert(pair<string, Node>(from, Node(from)));
if (graph.node.find(to) == graph.node.end())//如果to點從沒在哈希中出現過就加入
graph.node.insert(pair<string, Node>(to, Node(to)));
Node* p_fromNode = &graph.node.find(from)->second;//在哈希表中提出from點
Node* p_toNode = &graph.node.find(to)->second;//提出to點
p_fromNode->nextnode.push_back(*p_toNode);//from節點的next節點是to
++p_fromNode->out;//from的出度++
++p_toNode->in;//to節點的入度++
Edge newedge = Edge(weight, p_fromNode, p_toNode);//建立一條邊
p_fromNode->edge.push_back(newedge);//把這條邊加入到from點的邊集中
graph.edge.insert(newedge);//把這條邊加入到圖中
}
}
int bfs(Graph graph, string beginWord, string endWord)
{
queue<pair<string,int> >a;
a.push(pair<string,int>(beginWord,1));
unordered_set<string>b;
int ret=0;
while(!a.empty())
{
pair<string,int>temp = a.front();
a.pop();
if(b.end() == b.find(temp.first)) ///<沒有訪問過這個節點
{
b.insert(temp.first);
auto it = graph.node.find(temp.first);
if(it == graph.node.end()) ///<找到的節點,任何一個節點的入度和出度都不會等於0,除非不是連通圖
break;
auto node_list = it->second.nextnode;
for(auto it1=node_list.begin(); node_list.end() != it1; ++it1)///直接遍歷鏈表
{
if(endWord==it1->value )
{
ret = temp.second;
return ret/2+1;
}
if(b.end() == b.find(it1->value))
a.push(pair<string,int>(it1->value,temp.second+1));
}
}
}
return 0;
}
int ladderLength(string beginWord, string endWord, vector<string>& wordList)
{
wordList.push_back(beginWord);
// wordList.push_back(endWord);
vector<vector<string> >a;
for(int i=0;i<(int)wordList.size();++i)
{
vector<string>temp(3);
temp[0]="0";
for(int j=0;j<3;++j)
{
string from = wordList[i];
string to = from;
to[j]='*';
temp[1]=from;
temp[2]=to;
a.push_back(temp);
temp[1]=to;
temp[2]=from;
a.push_back(temp);
}
}
ReadGraph(a);
return bfs(graph,beginWord,endWord);
}
int main(void)
{
string x[]={"most","mist","miss","lost","fist","fish"};
vector<string> b(begin(x),end(x));
cout<< ladderLength("lost","miss",b)<<endl;
return 0;
}
臨時保存leetcode單詞接龍,有點問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.