我正在使用Djikstra算法在图中搜索特殊路径的小程序。算法上它是正确的 - 我对此100%确定。基本上,对正常Djikstra的唯一修改是当边的值是对时,它们以特殊方式进行比较。另外,Djikstra返回2个路径长度。C++ sigabrt推向矢量
这里的任务和细节并不重要,因为我的程序由于与它完全无关的事情而失败,我似乎无法找到原因。读取输入并将其放入结构时失败。
输入格式如下:n =顶点数,m =边数,q =问题数。比描述边的m行要多:vertex1,vertex2,value,charValue是N还是B.之后有q个问题询问起始和结束之间的最短路径。我越来越
SIGABRT free(): invalid pointer: 0x000000000060b0d0
(指针的数量是不同的,当然所有的时间)上线97上的push_back() 输入的最后行工作期间,当我输入的是这样的:
6 11 5
0 1 6 B
0 3 5 N
0 3 10 B
0 4 0 N
0 5 2 B
5 2 7 N
5 4 1 B
4 1 3 N
(输入未完成 - 仍然有一些边缘和问题,但它始终在相同的地方失败)
我试过Valgrind没有成功。代码是这样的:
#include <iostream>
#include <vector>
#include <limits>
#include <set>
using namespace std;
struct myStruct{
long long n,b;
int vertex;
};
struct comparator {
bool operator() (const myStruct& left, const myStruct& right) const{
if (left.n == right.n){
return left.b < right.b;
} else {
return left.n < right.n;
}
}
};
pair<long long, long long> customDjikstra(int start, int end, int n,vector< vector<myStruct> > &graf){ //djikstra
vector<pair<long long,long long> > djikstraLengthPaths;
set< myStruct , comparator > orderedSet;
djikstraLengthPaths.reserve(n);
for(int i = 0; i < n; i++){
djikstraLengthPaths.push_back(make_pair(numeric_limits<long long>::max(),numeric_limits<long long>::max()));
}
djikstraLengthPaths[start].first = 0;
djikstraLengthPaths[start].second = 0;
vector<bool> visited;
visited.resize(n);
myStruct tmp,currentVertex;
tmp.b = 0;
tmp.n = 0;
tmp.vertex = start;
orderedSet.insert(tmp);
while(!orderedSet.empty()){
currentVertex = (*orderedSet.begin());
orderedSet.erase(orderedSet.begin());
if (visited[currentVertex.vertex]){
continue;
}
visited[currentVertex.vertex] = true;
for(int j = 0; j < graf[currentVertex.vertex].size();j++){
myStruct edge = graf[currentVertex.vertex][j];
if(djikstraLengthPaths[edge.vertex].first > currentVertex.n + edge.n || (djikstraLengthPaths[edge.vertex].first == currentVertex.n + edge.n && djikstraLengthPaths[edge.vertex].second > currentVertex.b + edge.b)){ //ak to zlepsi hodnotu nasej cesty, updatneme to
djikstraLengthPaths[edge.vertex].first = currentVertex.n + edge.n;
djikstraLengthPaths[edge.vertex].second = currentVertex.b + edge.n + edge.b;
tmp.n = djikstraLengthPaths[edge.vertex].first;
tmp.b = djikstraLengthPaths[edge.vertex].second;
tmp.vertex = edge.vertex;
orderedSet.insert(tmp);
}
}
}
return djikstraLengthPaths[end];
}
int main() {
int n,m,q;
cin >> n >> m >> q;
vector<vector<myStruct> > graf(n);
myStruct temp;
int a,b,c;
char d;
bool flag;
for(int f = 0; f < m;f++){
int i;
cin >> a >> b >> c >> d;
flag = 0;
/*Graph is list of neighbours*/
for(i = 0; i < graf[a].size();i++){
if(graf[a][i].vertex == b){
flag = 1;
break;
}
}
if(d == 'N'){
if(!flag){
temp.n = c;
temp.b = 0;
temp.vertex = b;
graf[a].push_back(temp);
temp.n = c;
temp.b = 0;
temp.vertex = a;
graf[b].push_back(temp);
} else if(graf[a][i].n > c) {
graf[a][i].n = c;
graf[a][i].b = 0;
graf[b][i].n = c;
graf[b][i].b = 0;
}
}else {
if(!flag){
temp.n = 0;
temp.b = c;
temp.vertex = b;
graf[a].push_back(temp);
temp.n = 0;
temp.b = c;
temp.vertex = a;
graf[b].push_back(temp);
} else if(graf[a][i].n > 0 || graf[a][i].b > c) {
graf[a][i].n = 0;
graf[a][i].b = c;
graf[b][i].n = 0;
graf[b][i].b = c;
}
}
}
int start,end;
pair<long long, long long> answer;
for(int j = 0; j < q;j++){
cin >> start >> end;
answer = customDjikstra(start,end,n,graf);
if(answer.first == numeric_limits<long long>::max()){
cout << "-1 -1" << endl;
} else {
cout << answer.first << ' ' << answer.second << endl;
}
}
}
如果你能帮助我,告诉我什么我做错了,忘了初始化或类似的东西,这将是巨大的。
对于此长度的摘录,可以包含行号还是直观指示第97行?人们不愿意数它们或将代码提取到外部编辑器中。 –
无论如何,我怀疑是在这里的某个地方,由于所有的迭代器和循环都继续,迭代器被无效。我会试着更近一些...... –
我不会开始剖析根本原因,但是在你的'if(d =='N')'条件的其他情况下,'graf的访问器[b] [i]'(用过两次)超出了你的界限。我看到的具体可重复的情况是'b == 3'和'i == 1'的位置。那时,'graf [b]'子向量只有一个项目,因此它只能由'0'索引。 – WhozCraig