Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c25c409

Browse files
Update
1 parent e3c4c20 commit c25c409

8 files changed

+891
-13
lines changed

‎problems/0207.课程表.md‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
拓扑排序指的是一种 解决问题的大体思路, 而具体算法,可能是 广搜 可能是深搜。
3+
4+
大家可能发现 各式各样的解法,纠结哪个是拓扑排序?
5+
6+
只要能在把 有向无环图 进行线性排序 的算法 都可以叫做 拓扑排序。
7+
8+
引用与任务调度,课程安排等等。
9+
10+
为什么
11+
12+
13+
-----
14+
15+
「拓扑排序」是专门应用于有向图的算法;
16+
17+
把一个 有向无环图 转成 线性的排序 就叫 拓扑排序。
18+
19+
拓扑排序(Kahn 算法,其实就是广度优先遍历的思路)
20+
21+
这道题的做法同样适用于第 210 题。
22+
23+
------------------
24+
25+
```
26+
vector<int> inDegree(numCourses);
27+
unordered_map<int, vector<int>> map;
28+
for (int i = 0; i < prerequisites.size(); i++) {
29+
inDegree[prerequisites[i][0]]++;//当前课程入度值+1
30+
map[prerequisites[i][1]].push_back(prerequisites[i][0]);//添加依赖他的后续课
31+
}
32+
queue<int> Qu;
33+
for (int i = 0; i < numCourses; i++) {
34+
if (inDegree[i] == 0) Qu.push(i);//所有入度为0的课入列
35+
}
36+
int count = 0;
37+
while (Qu.size()) {
38+
int selected = Qu.front(); //当前选的课
39+
Qu.pop();//出列
40+
count++;//选课数+1
41+
vector<int> toEnQueue = map[selected];//获取这门课对应的后续课
42+
if (toEnQueue.size()) { //确实有后续课
43+
for (int i = 0; i < toEnQueue.size(); i++) {
44+
inDegree[toEnQueue[i]]--; //依赖它的后续课的入度-1
45+
if (inDegree[toEnQueue[i]] == 0) Qu.push(toEnQueue[i]); //如果因此减为0,入列
46+
}
47+
}
48+
}
49+
if (count == numCourses) return true;
50+
return false;
51+
```

‎problems/0743.网络延迟时间.md‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,8 +1194,7 @@ public:
11941194

11951195
至此通过 两篇dijkstra的文章,终于把 dijkstra 讲完了,如果大家对我讲解里所涉及的内容都吃透的话,详细对 dijkstra 算法也就理解到位了。
11961196

1197-
1198-
# Bellman_ford
1197+
这里在给出本题的Bellman_ford解法,关于 Bellman_ford ,后面我会专门来讲解的,Bellman_ford 有其独特的应用场景
11991198

12001199
```CPP
12011200
class Solution {
@@ -1204,27 +1203,25 @@ public:
12041203
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
12051204
vector<int> minDist(n + 1 , INT_MAX/2);
12061205
minDist[k] = 0;
1207-
vector<int> minDist_copy(n); // 用来记录每一次遍历的结果
1206+
//vector<int> minDist_copy(n); // 用来记录每一次遍历的结果
12081207
for (int i = 1; i <= n + 1; i++) {
1209-
minDist_copy = minDist; // 获取上一次计算的结果
1208+
//minDist_copy = minDist; // 获取上一次计算的结果
12101209
for (auto &f : times) {
12111210
int from = f[0];
12121211
int to = f[1];
1213-
int price = f[2];
1214-
if (minDist[to] > minDist_copy[from] + price) minDist[to] = minDist_copy[from] + price;
1215-
}
1212+
int price = f[2];
1213+
if (minDist[to] > minDist[from] + price) minDist[to] = minDist[from] + price;
1214+
}
12161215

12171216
}
1218-
int result = 0;
1217+
int result = 0;
12191218
for (int i = 1;i <= n; i++) {
12201219
if (minDist[i] == INT_MAX/2) return -1;// 没有路径
12211220
result = max(minDist[i], result);
12221221
}
1223-
12241222
return result;
12251223

12261224
}
12271225
};
1228-
12291226
```
12301227

‎problems/0787.K站中转内最便宜的航班.md‎

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11

2+
# 787. K 站中转内最便宜的航班
3+
4+
有 n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi。
5+
6+
现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线,使得从 src 到 dst 的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1。
7+
8+
9+
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240319103900.png)
10+
11+
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240319103919.png)
12+
13+
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240319104026.png)
14+
15+
16+
## 思路
17+
18+
219

320
```CPP
421
class Solution {
@@ -13,7 +30,8 @@ public:
1330
int from = f[0];
1431
int to = f[1];
1532
int price = f[2];
16-
if (minDist[to] > minDist_copy[from] + price) minDist[to] = minDist_copy[from] + price;
33+
minDist[to] = min(minDist_copy[from] + price, minDist[to]);
34+
// if (minDist[to] > minDist_copy[from] + price) minDist[to] = minDist_copy[from] + price;
1735
}
1836

1937
}
@@ -23,6 +41,8 @@ public:
2341
};
2442
```
2543

44+
下面是典型的错误写法
45+
2646
```CPP
2747
class Solution {
2848
public:
@@ -42,3 +62,117 @@ public:
4262
}
4363
};
4464
```
65+
66+
67+
-----------
68+
69+
SPFA
70+
71+
72+
class Solution {
73+
struct Edge {
74+
int to; // 链接的节点
75+
int val; // 边的权重
76+
77+
Edge(int t, int w): to(t), val(w) {} // 构造函数
78+
};
79+
80+
public:
81+
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
82+
vector<int> minDist(n , INT_MAX/2);
83+
vector<list<Edge>> grid(n + 1); // 邻接表
84+
for (auto &f : flights) {
85+
int from = f[0];
86+
int to = f[1];
87+
int price = f[2];
88+
grid[from].push_back(Edge(to, price));
89+
90+
}
91+
minDist[src] = 0;
92+
vector<int> minDist_copy(n); // 用来记录每一次遍历的结果
93+
k++;
94+
queue<int> que;
95+
que.push(src);
96+
std::vector<bool> visited(n + 1, false); // 可加,可不加,加了效率高一些,防止重复访问
97+
int que_size;
98+
while (k-- && !que.empty()) {
99+
100+
minDist_copy = minDist; // 获取上一次计算的结果
101+
que_size = que.size();
102+
while (que_size--) { // 这个while循环的设计实在是妙啊
103+
int node = que.front(); que.pop();
104+
for (Edge edge : grid[node]) {
105+
int from = node;
106+
int to = edge.to;
107+
int price = edge.val;
108+
if (minDist[to] > minDist_copy[from] + price) {
109+
minDist[to] = minDist_copy[from] + price;
110+
que.push(to);
111+
}
112+
}
113+
114+
}
115+
}
116+
int result = minDist[dst] == INT_MAX/2 ? -1 : minDist[dst];
117+
return result;
118+
}
119+
};
120+
121+
122+
-----------------
123+
124+
队列加上 visited 不能重复访问
125+
126+
class Solution {
127+
struct Edge {
128+
int to; // 链接的节点
129+
int val; // 边的权重
130+
131+
Edge(int t, int w): to(t), val(w) {} // 构造函数
132+
};
133+
134+
public:
135+
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
136+
vector<int> minDist(n , INT_MAX/2);
137+
vector<list<Edge>> grid(n + 1); // 邻接表
138+
for (auto &f : flights) {
139+
int from = f[0];
140+
int to = f[1];
141+
int price = f[2];
142+
grid[from].push_back(Edge(to, price));
143+
144+
}
145+
minDist[src] = 0;
146+
vector<int> minDist_copy(n); // 用来记录每一次遍历的结果
147+
k++;
148+
queue<int> que;
149+
que.push(src);
150+
int que_size;
151+
while (k-- && !que.empty()) {
152+
// 注意这个数组放的位置
153+
vector<bool> visited(n + 1, false); // 可加,可不加,加了效率高一些,防止队列里重复访问,其数值已经算过了
154+
minDist_copy = minDist; // 获取上一次计算的结果
155+
que_size = que.size();
156+
while (que_size--) {
157+
int node = que.front(); que.pop();
158+
for (Edge edge : grid[node]) {
159+
int from = node;
160+
int to = edge.to;
161+
int price = edge.val;
162+
if (minDist[to] > minDist_copy[from] + price) {
163+
minDist[to] = minDist_copy[from] + price;
164+
if(visited[to]) continue; // 不用重复放入队列,但需要重复计算,所以放在这里位置
165+
visited[to] = true;
166+
que.push(to);
167+
}
168+
}
169+
170+
}
171+
}
172+
int result = minDist[dst] == INT_MAX/2 ? -1 : minDist[dst];
173+
return result;
174+
}
175+
};
176+
177+
178+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
floyd
3+
4+
5+
class Solution {
6+
public:
7+
int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
8+
vector<vector<int>> grid(n, vector<int>(n, 10005)); // 因为边的最大距离是10^4
9+
10+
// 节点到自己的距离为0
11+
for (int i = 0; i < n; i++) grid[i][i] = 0;
12+
// 构造邻接矩阵
13+
for (const vector<int>& e : edges) {
14+
int from = e[0];
15+
int to = e[1];
16+
int val = e[2];
17+
grid[from][to] = val;
18+
grid[to][from] = val; // 注意这里是双向图
19+
}
20+
21+
// 开始 floyd
22+
// 思考 为什么 p 要放在最外面一层
23+
for (int p = 0; p < n; p++) {
24+
for (int i = 0; i < n; i++) {
25+
for (int j = 0; j < n; j++) {
26+
grid[i][j] = min(grid[i][j], grid[i][p] + grid[p][j]);
27+
}
28+
}
29+
}
30+
31+
int result = 0;
32+
int count = n + 10; // 记录所有城市在范围内连接的最小城市数量
33+
for (int i = 0; i < n; i++) {
34+
int curCount = 0; // 统计一个城市在范围内可以连接几个城市
35+
for (int j = 0; j < n; j++) {
36+
if (i != j && grid[i][j] <= distanceThreshold) curCount++;
37+
// cout << "i:" << i << ", j:" << j << ", val: " << grid[i][j] << endl;
38+
}
39+
if (curCount <= count) { // 注意这里是 <=
40+
count = curCount;
41+
result = i;
42+
}
43+
}
44+
return result;
45+
}
46+
};

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /