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

[pull] master from wisdompeak:master #320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
pull merged 7 commits into AlgorithmAndLeetCode:master from wisdompeak:master
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using state = tuple<int,int,int,int>;
class Solution {
public:
int minMoves(vector<string>& grid, int energy) {
int m = grid.size(), n = grid[0].size();

pair<int,int>start;
vector<pair<int,int>>litter_pos;
vector<vector<int>>litter_idx(m, vector<int>(n,-1));

for (int i=0; i<m; i++)
for (int j=0; j<n; j++) {
if (grid[i][j]=='S')
start = {i,j};
else if (grid[i][j]=='L')
{
litter_pos.push_back({i,j});
litter_idx[i][j] = litter_pos.size()-1;
}
}
int L = litter_pos.size();

vector<vector<vector<vector<bool>>>> visited(
m, vector<vector<vector<bool>>>(
n, vector<vector<bool>>(energy + 1, vector<bool>(1 << L, false))));

visited[start.first][start.second][energy][0] = true;

vector<pair<int,int>>dir={{0,1},{0,-1},{1,0},{-1,0}};

queue<state> q;
q.push({start.first, start.second, energy, 0});
int step = 0;

while (!q.empty())
{
int len = q.size();
while (len--)
{
auto [x,y,e,mask] = q.front();
q.pop();
if (mask==(1<<L)-1) return step;

for (int k=0; k<4; k++)
{
int nx = x+dir[k].first;
int ny = y+dir[k].second;
if (nx<0||nx>=m||ny<0||ny>=n) continue;

char cell = grid[nx][ny];
if (cell=='X') continue;

int newEnergy = e-1;
if (newEnergy < 0) continue;
if (cell == 'R') newEnergy = energy;

int newMask = mask;
if (grid[nx][ny]=='L')
{
int idx = litter_idx[nx][ny];
newMask |= (1<<idx);
}
if (!visited[nx][ny][newEnergy][newMask]) {
visited[nx][ny][newEnergy][newMask] = true;
q.emplace(nx, ny, newEnergy, newMask);
}
}
}
step++;
}

return -1;
}
};
5 changes: 5 additions & 0 deletions BFS/3568.Minimum-Moves-to-Clean-the-Classroom/Readme.md
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### 3568.Minimum-Moves-to-Clean-the-Classroom

典型的BFS,但是我们需要定义一个composite state来避免重复。本题中因为最有路径可能需要重复经过相同的cell,所以我们还需要记录每一步时当前的energy,已经访问过的litter。这样所有的状态种类有`20*20*50*2^10=2e7`,复杂度勉强够用。

具体的做法就是常规的BFS。每次从队列中弹出[x,y,energy,mask],其中mask是一个二进制数,用bit位来记录哪些编号的垃圾已经被清理。从当前[x,y]往四个方向尝试移动,每次移动需要更新energy(减一,或者遇到R就reset),也可能需要更新mask(即遇到L)。在将新状态加入队列之前,查看一下这个state之前是否已经加入过队列(即可以在更早的时间被访问到)以避免重复搜索。
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using ll = long long;
const int MAXN = 100000;
const int LOGN = 17;
class Solution {
public:
vector<pair<int,int>> adj[MAXN];
int up[MAXN][LOGN+1];
int depth[MAXN];
ll distRoot[MAXN];

void dfs(int cur, int parent)
{
up[cur][0] = parent;
for(auto &[v,w]: adj[cur])
{
if(v == parent) continue;
depth[v] = depth[cur] + 1;
distRoot[v] = distRoot[cur] + w;
dfs(v, cur);
}
}

int lca(int a, int b)
{
if(depth[a] < depth[b]) swap(a,b);
int diff = depth[a] - depth[b];
for(int k = 0; k <= LOGN; k++){
if(diff & (1<<k)) a = up[a][k];
}
if(a == b) return a;
for(int k = LOGN; k >= 0; k--){
if(up[a][k] != up[b][k]){
a = up[a][k];
b = up[b][k];
}
}
return up[a][0];
}

ll dist(int a, int b)
{
int c = lca(a,b);
return distRoot[a] + distRoot[b] - 2*distRoot[c];
}

vector<int> minimumWeight(vector<vector<int>>& edges, vector<vector<int>>& queries)
{
int n = edges.size()+1;

for (int i = 0; i < n-1; i++)
{
int u = edges[i][0], v = edges[i][1], w = edges[i][2];
adj[u].push_back({v,w});
adj[v].push_back({u,w});
}

depth[0] = 0;
distRoot[0] = 0;
dfs(0, 0);

for(int k = 1; k <= LOGN; k++) {
for(int v = 0; v < n; v++) {
up[v][k] = up[up[v][k-1]][k-1];
}
}

vector<int>rets;
for (auto& q: queries)
{
int u = q[0], v = q[1], w = q[2];
ll d_uv = dist(u,v);
ll d_vw = dist(v,w);
ll d_uw = dist(u,w);
ll ans = (d_uv + d_vw + d_uw) / 2;
rets.push_back(ans);
}

return rets;
}
};
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### 3553.Minimum-Weighted-Subgraph-With-the-Required-Paths-II

本题的第一个知识点是:在一棵树里,联通u,v,w三个节点的最小子树的权重和,就是`[dist(u,v)+dist(u,w)+dist(v,w)]/2`.
4 changes: 3 additions & 1 deletion Readme.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
[2836.Maximize-Value-of-Function-in-a-Ball-Passing-Game](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2836.Maximize-Value-of-Function-in-a-Ball-Passing-Game) (H)
[2846.Minimum-Edge-Weight-Equilibrium-Queries-in-a-Tree](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2846.Minimum-Edge-Weight-Equilibrium-Queries-in-a-Tree) (H)
[2851.String-Transformation](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2851.String-Transformation) (H+)
[3553.Minimum-Weighted-Subgraph-With-the-Required-Paths-II](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/3553.Minimum-Weighted-Subgraph-With-the-Required-Paths-II) (H)
* ``Binary Search by Value``
[410.Split-Array-Largest-Sum](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/410.Split-Array-Largest-Sum) (H-)
[774.Minimize-Max-Distance-to-Gas-Station](https://github.com/wisdompeak/LeetCode/tree/master/Priority_Queue/774.Minimize-Max-Distance-to-Gas-Station) (H)
Expand Down Expand Up @@ -621,7 +622,8 @@
[913.Cat-and-Mouse](https://github.com/wisdompeak/LeetCode/tree/master/BFS/913.Cat-and-Mouse) (H+)
[1728.Cat-and-Mouse-II](https://github.com/wisdompeak/LeetCode/tree/master/BFS/1728.Cat-and-Mouse-II) (H+)
[1293.Shortest-Path-in-a-Grid-with-Obstacles-Elimination](https://github.com/wisdompeak/LeetCode/tree/master/BFS/1293.Shortest-Path-in-a-Grid-with-Obstacles-Elimination) (H-)
[1928.Minimum-Cost-to-Reach-Destination-in-Time](https://github.com/wisdompeak/LeetCode/tree/master/BFS/1928.Minimum-Cost-to-Reach-Destination-in-Time) (H-)
[1928.Minimum-Cost-to-Reach-Destination-in-Time](https://github.com/wisdompeak/LeetCode/tree/master/BFS/1928.Minimum-Cost-to-Reach-Destination-in-Time) (H-)
[3568.Minimum-Moves-to-Clean-the-Classroom](https://github.com/wisdompeak/LeetCode/tree/master/BFS/3568.Minimum-Moves-to-Clean-the-Classroom) (H-)
* ``拓扑排序``
[207.Course-Schedule](https://github.com/wisdompeak/LeetCode/tree/master/BFS/207.Course-Schedule) (H-)
[210.Course-Schedule-II](https://github.com/wisdompeak/LeetCode/tree/master/BFS/210.Course-Schedule-II) (M)
Expand Down

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