题目概述
解题思路
这道题显然是采用单源最短路径去求解,我采用的是Dijkstra算法。这道题相当于除了要维护各个节点到起点的最短路径长度,还要维护到起点的代价。
我首先采用的构图方法是:设置一个二维数组,第一维是节点数目,第二维是每个节点的邻接节点数目——
class Edges
{
public:
int val,
dist,
cost;
Edges(int vi, int di, int ci): val(vi), dist(di), cost(ci) {}
};
我在每次碰到新的case的时候,都新建一个数组,用于维护每个节点与起点的最短路径长度。我们需要将该数组初始化为每个元素都是某个较大值。
接下来我发现,这种写法会碰到超时的情况:
我推测可能是在新建数组的时候花费了过长的时间,于是参照了博客中实现的思路,只生成一个数组,然后每次用memset去初始化它。
这种方法确实AC了,说明新建数组确实比较耗时。
方法性能
我的实现复杂度是O(V^2)。
代码示例
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<unordered_set>
int min_dist[1001];
int min_cost[1001];
class Edges
{
public:
int val, dist, cost;
Edges(int vi, int di, int ci):
val(vi), dist(di), cost(ci) {};
};
using namespace std;
int main()
{
int N, M;
while(scanf("%d%d", &N, &M) && (N * M))
{
//construct graph
vector<Edges> *Nodes = new vector<Edges> [N];
int src, tgt, dis, cos;
for (int mi = 0; mi < M;++mi)
{
scanf("%d%d%d%d", &src, &tgt, &dis, &cos);
Nodes[src - 1].push_back(Edges(tgt, dis, cos));
Nodes[tgt - 1].push_back(Edges(src, dis, cos));
}
scanf("%d%d", &src, &tgt);
memset(min_dist, 0x3f, sizeof(min_dist));
memset(min_cost, 0x3f, sizeof(min_cost));
// int *min_dist = new int[N];
// int *min_cost = new int[N];
// for (int mi = 0; mi < N; ++mi)
// {
// min_dist[mi] = 2147483647;
// min_cost[mi] = 2147483647;
// }
min_dist[src - 1] = 0;
min_cost[src - 1] = 0;
int cur_min, cur_idx, cur_cost;
unordered_set<int> unvis;
for (int ni = 0; ni < N; ++ni)
unvis.insert(ni + 1);
while(unvis.size())
{
//find shortest distance
cur_min = cur_cost = 2147483647;
for (unordered_set<int>::iterator iter = unvis.begin(); iter != unvis.end(); ++iter)
{
if(cur_min > min_dist[*iter - 1] ||
cur_min == min_dist[*iter - 1] && cur_cost > min_cost[*iter - 1])
{
cur_min = min_dist[*iter - 1];
cur_cost = min_cost[*iter - 1];
cur_idx = *iter - 1;
}
}
//remove node
unvis.erase(cur_idx + 1);
min_dist[cur_idx] = cur_min;
min_cost[cur_idx] = cur_cost;
//update dist list
for (int vi = 0, temp_len, temp_cos, temp_idx; vi < Nodes[cur_idx].size(); ++vi)
{
temp_idx = Nodes[cur_idx][vi].val - 1;
temp_len = Nodes[cur_idx][vi].dist + cur_min;
temp_cos = Nodes[cur_idx][vi].cost + cur_cost;
if(temp_len < min_dist[temp_idx] ||
(temp_len == min_dist[temp_idx] && temp_cos < min_cost[temp_idx]))
{
min_dist[temp_idx] = temp_len;
min_cost[temp_idx] = temp_cos;
}
}
}
printf("%d %d\n", min_dist[tgt - 1], min_cost[tgt - 1]);
}
return 0;
}