Problem: 2477. 到达首都的最少油耗
思路
本题的的油耗相当于相当于车的行驶路程(城市与城市之间的距离均为 1),进而题目转化为到首都的车辆总行驶距离;
既然题目是行驶到首都,那我们就得从树的叶节点走到根节点,尝试递归回溯;
对于某个节点 i
,我们贪心的将到达当前城市的人先聚集起来,再统一分配车(有一说一,一上一下太折磨代表了,但预算有限,市长也无能为力),这里计算车耗油也就是所有车行驶的总距离公式是 dist = ⌈person/seats⌉
,我们简单将向上取整用下面公式代替 dist = person + seats - 1 / seats
;
这也要求我们每回溯到一个节点就更新一次总距离(总耗油),即 cnt += dist
。
解题方法
- 采用邻接表构建树,注意此时的双向的;
- DFS,找到最后一个节点进行回溯,使用
visited
标记当前节点是否被访问过,若访问过则不返回节点总人数,若未访问过,则该层结束时返回当前节点的总人数(包括从外地路过本地的); - 每到一个节点进行人员车辆重新分配工作,即
dist = person + seats - 1 / seats
; - 总油耗加上当前节点的
dist
; - 由于首都(节点 0)不需要分配车子,因此再 DFS 之外需要减去 DFS 在根节点加上的
dist
。
复杂度
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
Code
class Solution {
public:
long long DFS(vector<vector<int>> &vertex, long long &cnt, int visited[], int &seats, int curr) {
if (visited[curr]) return 0;
long long person = 1;
visited[curr] = 1;
for (auto ver: vertex[curr]) {
person += DFS(vertex, cnt, visited, seats, ver);
}
cnt += (person + seats - 1) / seats;
return person;
}
long long minimumFuelCost(vector<vector<int>>& roads, int seats) {
long long cnt = 0;
int visited[roads.size()+1];
vector<vector<int>> vertex(roads.size()+1);
memset(visited, 0, sizeof(visited));
for (auto road: roads) {
vertex[road[0]].push_back(road[1]);
vertex[road[1]].push_back(road[0]);
}
DFS(vertex, cnt, visited, seats, 0);
cnt -= (roads.size() + seats) / seats;
return cnt;
}
};