The camel T10 door of the king [test boring game] Treasure

Code agricultural problem. Moderate difficulty thinking, difficulty in debugging

Construction Method edge: x and y are sorted, for each point, all of its next x / y even side (if he needed) to open the recording position of map points, for each point, if the squares within his there are other points, he was not even on the right side

Note Sorting make points of order, it is necessary to state in the save point id

End shrink even while running tarjan point is easy to prove if you can come to a point in a ring, you can reach every point in the ring. The weight of each ring is the number of points inside him. The individual rings FIG into a new

Can discover new map has been transformed into a DAG. Can choose dfs / topo to record the answers. Here I choose to use dfs.

Each point has not been dfs counts the number of points can be obtained through this treasure, the maximum value

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <unordered_map>
#include <cstring>
#include <stack>
using namespace std;
const int MAXN = 1e5+5;
int n,r,c,dp[MAXN],curr,ans;

int pre,dfn[MAXN],low[MAXN],head[MAXN],num[MAXN],in[MAXN];
unordered_map<int, unordered_map<int,int> > mp, inq;
vector<int> adj[MAXN],adj2[MAXN],tmp[MAXN];
stack<int> st;
int x_[8] = {1,0,-1,0,1,1,-1,-1};
int y_[8] = {0,1,0,-1,1,-1,1,-1};//九宫格
bool vis[MAXN];
struct Edge{
  int x,y,type,id;
}edge[MAXN],edge2[MAXN];
inline bool sorted1(Edge a, Edge b){
  return a.x<b.x || (a.x==b.x && a.type==1);
}//x排序
inline bool sorted2(Edge a, Edge b){
  return a.y<b.y || (a.y==b.y && a.type==2);
}//y排序
inline void add_x(){
  sort(edge+1,edge+n+1,sorted1);
  int prev = 0;
  for (int i=1;i<=n;i++){
    if (edge[i].type!=1) continue;//如果他自己不能连
    int f = edge[i].id;
    int nxt = i-1;
    while(nxt>0){
      if (edge[nxt].x!=edge[i].x) break;
      int t = edge[nxt].id;
      adj[f].push_back(t);
      nxt--;
    }//往左连
    nxt = i+1;
    while(nxt<=n){
      int t = edge[nxt].id;
      if (edge[nxt].x!=edge[i].x) break;
      adj[f].push_back(t);
      nxt++;
    }//往右连
  }
}
inline void add_y(){
  sort(edge+1,edge+n+1,sorted2);
  int prev = 0;
  for (int i=1;i<=n;i++){
    if (edge[i].type!=2) continue;
    int f = edge[i].id;
    int nxt = i-1;
    while(nxt>0){//往左
      int t = edge[nxt].id;
      if (edge[nxt].y!=edge[i].y) break;
      adj[f].push_back(t);
      nxt--;
    }
    nxt = i+1;
    while(nxt<=n){//往右
      int t = edge[nxt].id;
      if (edge[nxt].y!=edge[i].y) break;
      adj[f].push_back(t);
      nxt++;
    }
  }
}
inline void add_xy(){//九宫格连
  for (int i=1;i<=n;i++){
    if (edge[i].type!=3) continue;
    int f = edge[i].id;
    for (int j=0;j<8;j++){
      int to_x = edge[i].x+x_[j], to_y = edge[i].y+y_[j];
      if (mp[to_x][to_y] ){
        int t = mp[to_x][to_y];
        if (!inq[f][t]){inq[f][t] = true;adj[f].push_back(t);}
      }
    }
  }
}
void tarjan(int pos){//裸的tarjan
  st.push(pos);
  vis[pos] = true;
  dfn[pos] = low[pos] = ++pre;
  for (int v : adj[pos]){
    if (!dfn[v]){
      tarjan(v);
      low[pos] = min(low[pos],low[v]);
    }else if (vis[v]) low[pos] = min(low[pos],dfn[v]);
  }
  if (dfn[pos]==low[pos]) {
    curr++;
    while(st.size()){
      int stt = st.top();
      head[stt] = curr;
      tmp[curr].push_back(stt);
      num[curr]++;
      st.pop();
      vis[stt] = false;
      if (stt==pos) break;
    }
  }
}
void dfs(int pos){//dfs找子叶权值
  dp[pos] = num[pos];
  int addi = 0;
  for (int v : adj2[pos]){
    if (!dp[v]) dfs(v);
    addi = max(addi,dp[v]);
  }
  dp[pos]+=addi;
}
int main(){
  cin >> n >> r >> c;
  for (int i=1;i<=n;i++) {
    cin >> edge[i].x  >> edge[i].y >> edge[i].type;edge[i].id = i;
    edge2[i] = edge[i];
    mp[edge[i].x][edge[i].y] = i;
  }
  add_x();
  add_y();
  add_xy();
  for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
  
  for (int i=1;i<=curr;i++){//建新图
    memset(vis,0,sizeof(vis));
    vis[i] = true;
    for (int u : tmp[i]){
      for (int v : adj[u]){
        if (!vis[head[v]]){
          vis[head[v]] = true;
          adj2[i].push_back(head[v]);
        }
      }
    }
  }
  memset(vis,0,sizeof(vis));
  for (int i=1;i<=curr;i++){//找答案
    if (!vis[i]){
      dfs(i);
      ans = max(ans,dp[i]);
    }
  }
  cout << ans;
}

Guess you like

Origin www.cnblogs.com/DannyXu/p/12536357.html