对图进行多次dfs,在下次调用的时候,辅助数据结构中的数据需要重新进行初始化,否则将会出现难以发现的Bug。如下代码中对创建的图进行了多次的dfs,需要将path数组clear掉,visited数组重新初始化为false。
Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.
Example:
Given a / b = 2.0, b / c = 3.0.
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
return [6.0, 0.5, -1.0, 1.0, -1.0 ].
The input is:
vector <pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries
, where equations.size() == values.size()
, and the values are positive. This represents the equations. Return vector<double>
.
#include <iostream>
#include <vector>
#include <string>
#include <assert.h>
#include <map>
using namespace std;
struct Edge
{
int to;
double cost;
Edge(int to, double cost) : to(to), cost(cost) {}
};
class Solution
{
map<string, int> myMap; // string - id
vector<vector<Edge> > graph;
vector<double> res;
vector<bool> visited;
vector<double> path;
int id_pool;
void dispGraph()
{
for (int i = 0; i < graph.size(); ++i) {
cout << i <<": ";
for (int j = 0; j < graph[i].size(); ++j) {
cout << "(" << graph[i][j].to << "," << graph[i][j].cost <<") ";
}
cout << endl;
}
}
double calcMul(vector<double> &ns)
{
double res = 1.0;
for (int i = 0; i < ns.size(); ++i)
res *= ns[i];
return res;
}
bool dfs(const int s, const int d, vector<double> &path)
{
cout << s << " " << d << endl;
visited[s] = true;
if (s == d) {
return true;
}
vector<Edge> &es = graph[s];
for (int i = 0; i < es.size(); ++i) {
if (!visited[es[i].to]) {
path.push_back(es[i].cost);
if (dfs(es[i].to, d, path))
return true;
path.pop_back();
}
}
return false;
}
public:
vector<double> calcEquation(vector<pair<string, string> > equations, vector<double>& values, vector<pair<string, string> > queries)
{
// build graph
assert(equations.size() == values.size());
id_pool = 0;
for (int i = 0; i < equations.size(); ++i)
{
string &A = equations[i].first, &B = equations[i].second;
int id_A, id_B;
if (myMap.find(A) == myMap.end()) {
graph.push_back(vector<Edge>());
myMap[A] = id_A = id_pool;
id_pool++;
}
else
id_A = myMap[A];
if (myMap.find(B) == myMap.end()) {
graph.push_back(vector<Edge>());
myMap[B] = id_B = id_pool;
id_pool++;
}
else
id_B = myMap[B];
double val = values[i];
graph[id_A].push_back(Edge(id_B, val));
graph[id_B].push_back(Edge(id_A, 1/val));
}
dispGraph();
// find path
visited = vector<bool>(id_pool, false);
for (int i = 0; i < queries.size(); ++i)
{
string &A = queries[i].first, &B = queries[i].second;
if (myMap.find(A) == myMap.end() || myMap.find(B) == myMap.end()) {
res.push_back(-1.0);
continue;
}
int id_A = myMap[A], id_B = myMap[B];
// dfs
path.clear(); // path需要清理掉
visited.assign(id_pool, false); // visited需要重新赋值为false
if (dfs(id_A, id_B, path)) {
res.push_back(calcMul(path));
}
else
res.push_back(-1.0);
}
return res;
}
};
int main()
{
int n;
string A, B;
double div;
vector<pair<string, string> > equations;
vector<double> values;
(cin >> n).get();
for (int i = 0; i < n; ++i)
{
(cin >> A >> B >> div).get();
equations.push_back(make_pair(A, B));
values.push_back(div);
}
vector<pair<string, string> > queries;
(cin >> n).get();
for (int i = 0; i < n; ++i)
{
(cin >> A >> B).get();
queries.push_back(make_pair(A, B));
}
vector<double> ret = Solution().calcEquation(equations, values, queries);
for (int i = 0; i < ret.size(); ++i)
cout << ret[i] << " ";
cout << endl;
return 0;
}
/*
2
a b 2.0
b c 3.0
5
a c
b a
a e
a a
x x
output: 6.0 0.5 -1.0 1.0 -1.0
*/