图的创建
无向图 ,用链表数组创建每个路径,由于是无向,所以一条路径我们加入两个链表
List<Integer>[] g=new List[n];
//初始化数组中每个链表
for(List<Integer> gg:g){
gg=new ArrayList<>();
}
//添加每个路径
for(int[] road:roads){
g[road[0]].add(road[1]);
g[road[1]].add(road[0]);
}
思路:
到达地是0,根据题意,我们可以按照以下方法逐步分析:
直接到0 的有三个地方 : 1, 4, 5
这些地方到0 所耗费的油量就取决于 当前地方 有多少人:
比如此时地方1 中 有3个人要去0(分别是1,3,2 的 人),
那么从地方1 到 地方0 的耗油量 就是 (3-1) /seats +1
耗油量 是 固定公式 ,所以题目 就转换为了 求 每个地方 有多少人
举个栗子,
咱们顺着刚才的地方1继续往下推导:
直接到1 的有一个地方 :3
地方3有几个人? 2个(本地人3和 外地人2) 那么从3 到1 的耗油量 就是 (2-1) /seats +1
直接到3 的有一个地方 :2
地方2有几个人? 1个(本地人2) 那么从2 到3 的耗油量 就是 (1-1) /seats +1
那么对于写代码的过程来说:
就是遍历每个节点,然后计算该节点当前有多少人 ??
再计算耗油量 :耗油量的意义是 当前城市的这批人 去目的城市 的耗油量
确定递归参数和返回值:
参数:当前地 ,目的地,路径图 ,座位
返回值:当前城市人数(人数是逐渐累加的)
代码
class Solution {
public long minimumFuelCost(int[][] roads, int seats) {
int n= roads.length+1;
List<Integer>[] g=new List[n];
for (int i = 0; i < n; i++) {
g[i] = new ArrayList<>();
}
for(int[] road:roads){
g[road[0]].add(road[1]);
g[road[1]].add(road[0]);
}
dfs(0,-1,g,seats);
return gas;
}
long gas=0;
public int dfs(int x,int father,List<Integer>[] g,int seats){
//遍历子节点,计算有多少son
int son=0;
for(int city:g[x]){
if(city==father) continue;
son+=dfs(city,x,g,seats);
}
//现在总共有son子节点+1 自身的数量的人在x城市,要去father城市的耗油量是以下
if(x!=0) {
gas += (son + 1 - 1) / seats + 1;
}
return son+1;
}
}