社区讨论

神之 UKE

P4294[WC2008] 游览计划参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mhj324im
此快照首次捕获于
2025/11/03 19:55
4 个月前
此快照最后确认于
2025/11/03 19:55
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>

using namespace std;

const int N = 12;
const int M = (1 << 10) + 5;
const int INF = 5e7;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};

struct Node{
  int x, y;
  long long cnt;
  bool operator < (const Node &b) const{
    return cnt > b.cnt;
  }
};

struct node{
  int x, y, state;
}pre[N][N][M], p[N][N];

bool vis[N][N];
long long dist[N][N];
priority_queue<Node> heap;
int n, m, tot, a[N][N], id[N][N], dp[N][N][M], ans[N][N];
//(n - 1) * (i - 1) + j - 1

bool Record(int x, int y, long long cnt){
  if(cnt >= dist[x][y]) return 0;
  dist[x][y] = cnt, heap.push({x, y, cnt});
  return 1;
}

void dfs(int x, int y, int state){
  if(!x) return ;
  //cout << x << ' ' << y << ' ' << state << ' ' << dp[x][y][state] << '\n';
  ans[x][y] = 1;
  dfs(pre[x][y][state].x, pre[x][y][state].y, pre[x][y][state].state);
  if(x == pre[x][y][state].x && y == pre[x][y][state].y){
    dfs(pre[x][y][state].x, pre[x][y][state].y, state - pre[x][y][state].state);
  }
}

void print(){
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      if(a[i][j] == 0){
        cout << 'x';
      }
      else if(ans[i][j] == 1){
        cout << 'o';
      }
      else{
        cout << '-';
      }
    }
    cout << '\n';
  }
}

int main(){
  cin >> n >> m;
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      cin >> a[i][j];
      if(a[i][j] == 0){
        id[i][j] = tot++;
      }
    }
  }
  if(tot == 0){
    cout << 0 << '\n';
    for(int i = 1; i <= n; i++){
      for(int j = 1; j <= m; j++){
        cout << '-';
      }
      cout << '\n';
    }
    return 0;
  }
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      for(int k = 0; k < (1 << tot); k++){
        dp[i][j][k] = INF;
      }
    }
  }
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      dp[i][j][0] = 0;
      if(a[i][j] == 0){
        dp[i][j][(1 << id[i][j])] = 0;
      }
      else{
        dp[i][j][0] = a[i][j];
      }
    }
  }
  for(int k = 0; k < (1 << tot); k++){
    for(int i = 1; i <= n; i++){
      for(int j = 1; j <= m; j++){
        for(int s = k; s; s = (s - 1) & k){
          int num = dp[i][j][s] + dp[i][j][k - s] - a[i][j];
          if(num < dp[i][j][k]){
            dp[i][j][k] = num;
            pre[i][j][k] = {i, j, s};
          }
        }
      }
    }
    for(int i = 1; i <= n; i++){
      for(int j = 1; j <= m; j++){
        vis[i][j] = 0, dist[i][j] = INF + 5;
      }
    }
    for(int i = 1; i <= n; i++){
      for(int j = 1; j <= m; j++){
        p[i][j] = {0, 0, 0};
        if(dp[i][j][k] < INF){
          Record(i, j, dp[i][j][k]);
        }
      }
    }
    while(!heap.empty()){
      Node q = heap.top();
      heap.pop();
      if(vis[q.x][q.y]) continue;
      vis[q.x][q.y] = 1;
      for(int dir = 0; dir < 4; dir++){
        int nx = q.x + dx[dir], ny = q.y + dy[dir];
        if(nx >= 1 && nx <= n && ny >= 1 && ny <= m){
          if(Record(nx, ny, q.cnt + a[nx][ny])){
            p[nx][ny] = {q.x, q.y, k};
          }
        }
      }
    }
    for(int i = 1; i <= n; i++){
      for(int j = 1; j <= m; j++){
        if(dp[i][j][k] > dist[i][j]){
          pre[i][j][k] = p[i][j];
        }
        dp[i][j][k] = dist[i][j];
        //cout << i << ' ' << j << ' ' << k << ' ' << dp[i][j][k] << '\n';
      }
    }
  }
  int ans = INF;
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      ans = min(ans, dp[i][j][(1 << tot) - 1]);
    }
  }
  cout << ans << '\n';
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      if(ans == dp[i][j][(1 << tot) - 1]){
        dfs(i, j, (1 << tot) - 1);
        print();
        return 0;
      }
    }
  }
  return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...