首页 > 其他分享 >20241015

20241015

时间:2024-10-15 21:02:56浏览次数:1  
标签:20241015 cnt cur int now dp dis

P1037 易形迷宫(maze)

我们可以转化一下题面,把胸口碎大石的功能换成幽灵,可以直接穿透石头,那么我们可以把炸碎石头改成可以向 \(8\) 个方向随便走 \(k - 1\) 步,然后我们直接 \(dij\) 即可

#include <bits/stdc++.h>

using namespace std;

using Pii = pair<int, int>;

const int N = 2500 + 5;

struct node {
  int cnt, now;
};

struct qnode {
  int x, y, cnt, now;
  bool operator < (const qnode &e) const {
    return e.cnt == cnt ? now < e.now : cnt > e.cnt;
  }
};

int n, m, k, sx, sy, tx, ty;

int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};

vector<char> a[N];

vector<node> dis[N];

priority_queue<qnode> q;

void Record(int opt, int x, int y, int cnt, int now) {
  if (x < 1 || y < 1 || x > n || y > m) {
    return ;
  }
  if (opt == 1 && a[x][y] == '#' && !now) {
    cnt++, now = k;
  }
  now = max(0, now - 1);
  if ((cnt == dis[x][y].cnt && now > dis[x][y].now) || cnt < dis[x][y].cnt) {
    dis[x][y] = (node){cnt, now};
    q.push({x, y, cnt, now});
  }
}

void dij() {
  Record(1, sx, sy, 0, 0);
  while (!q.empty()) {
    qnode cur = q.top();
    q.pop();
    if ((dis[cur.x][cur.y].cnt == cur.cnt && dis[cur.x][cur.y].now > cur.now) || cur.cnt > dis[cur.x][cur.y].cnt) {
      continue;
    }
    for (int i = 0; i < 4; i++) {
      Record(1, cur.x + dx[i], cur.y + dy[i], cur.cnt, cur.now);
    }
    if (!cur.now) {
      continue;
    }
    for (int i = 4; i < 8; i++) {
      Record(2, cur.x + dx[i], cur.y + dy[i], cur.cnt, cur.now);
    }
  }
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  freopen("maze.in", "r", stdin);
  freopen("maze.out", "w", stdout);
  cin >> n >> m >> k;
  cin >> sx >> sy;
  cin >> tx >> ty;
  for (int i = 0; i <= n + 1; i++) {
    a[i].resize(m + 1);
    dis[i].resize(m + 1);
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> a[i][j];
      dis[i][j] = {(int)(1e9), (int)(-1e9)};
    }
  }
  dij();
  cout << dis[tx][ty].cnt;
  return 0;
}

训练山猫(lynx)

我们可以先将每个点按照高度排序,然后设 \(dp_i\) 表示从第 \(i\) 个点出发最大可以走多少步

那么我们可以预处理出如果将 \(i\) 相邻的连通块中最大的点,假设为 \(j\) 那么就有转移 \(dp_i = dp_j + dist(i, j)\)

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 2e5 + 5;

struct node {
  int h, id;
}a[N];

int n, dep[N], dp[N][25], f[N], fa[N], b[N];

vector<int> g[N];

void dfs(int u, int f) {
  dep[u] = dep[f] + 1;
  dp[u][0] = f;
  for (int i = 1; (1 << i) <= dep[u]; i++) {
    dp[u][i] = dp[dp[u][i - 1]][i - 1];
  }
  for (auto v : g[u]) {
    if (v == f) continue;
    dfs(v, u);
  }
}

int lca(int a, int b) {
  if (dep[a] < dep[b]) swap(a, b);
  for (int i = 20; i >= 0; i--) {
    if (dep[dp[a][i]] >= dep[b]) {
      a = dp[a][i];
    }
  }
  if (a == b) return a;
  for (int i = 20; i >= 0; i--) {
    if (dp[a][i] != dp[b][i]) {
      a = dp[a][i];
      b = dp[b][i];
    }
  }
  return dp[a][0];
}

int dist(int a, int b) {
  return dep[a] + dep[b] - 2 * dep[lca(a, b)];
}

bool cmp(node _x, node _y) {
  return _x.h < _y.h;
}

int find(int x) {
  if (fa[x] == x) {
    return x;
  }
  return fa[x] = find(fa[x]);
}

signed main() {
  freopen("lynx.in", "r", stdin);
  freopen("lynx.out", "w", stdout);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i].h;
    a[i].id = i;
    b[i] = a[i].h;
  }
  for (int i = 1, u, v; i < n; i++) {
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1, 0);
  sort(a + 1, a + n + 1, cmp);
  for (int i = 1; i <= n; i++) {
    fa[i] = i;
  }
  f[a[1].id] = 0;
  for (int i = 2; i <= n; i++) {
    for (auto cur : g[a[i].id]) {
      if (b[a[i].id] > b[cur]) {
        f[a[i].id] = max(f[a[i].id], f[find(cur)] + dist(find(cur), a[i].id));
        fa[find(cur)] = a[i].id;
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    ans = max(ans, f[i]);
  }
  cout << ans;
  return 0;
}

标签:20241015,cnt,cur,int,now,dp,dis
From: https://www.cnblogs.com/libohan/p/18468421

相关文章

  • 校测 20241015 图论
    保龄了!因为图论只自学过最短路Problem1.礼物分配为了庆祝大佬\(wxh\)的生日,众人决定为他准备礼物。现在有\(n\)个礼品盒排成一行,从\(1\)到n编号,每个礼品盒中可能有\(1\)个或\(0\)个礼品。大佬\(wxh\)提出了\(m\)个要求,形如“第\(l[i]\)到第\(r[i]\)个礼品......
  • cvpr注意事项和注册流程(2025版)(20241015更新还未开放注册)
    本文章基于现有网上没有cvpr详细版本的一步一步的注册流程进行编写,用于指导自己和方便他人进行注册。接下来将从CVPR2025的重要节点、变更事项、注册流程进行说明重要节点CVPR2025变更的重要事项Duetothedramaticincreaseinthenumberofsubmissionsandthedeterio......