[SDOI2010] the king's treasure camel door

Face questions

https://www.luogu.org/problem/P2403

answer

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<utility>
#include<algorithm>
#include<map>
#define ri register int
#define N 100500
using namespace std;
const int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={1,0,-1,1,-1,1,0,-1};
int n,r,c;
int dfn[N],low[N],tot=0,inq[N],stk[N],top=0;
int f[N];
int bel[N],cc=0;
int x[N],y[N],t[N];
map<pair<int,int>,int> ot;
vector<pair<int,int> > e;
vector<int> about[N];
int val[N];

int idx[N],cntx=0,idy[N],cnty=0;
vector<int> to[N];

void add_edge(int x,int y) {
  e.push_back(make_pair(x,y));
  to[x].push_back(y);
}

bool cmpx(int a,int b) {
  return x[a]<x[b] ||(x[a]==x[b] && y[a]<y[b]);
}
bool cmpy(int a,int b) {
  return y[a]<y[b] ||(y[a]==y[b] && x[a]<x[b]);
}

void linkx() {
  sort(idx+1,idx+cntx+1,cmpx);
  for (ri i=1;i<=cntx;i++) {
    if (x[idx[i]]==x[idx[i+1]]) add_edge(idx[i],idx[i+1]);
    else {
      for (ri j=i;;j--) if (x[idx[j]]==x[idx[i]] && x[idx[j-1]]!=x[idx[i]]) 
      {
        if (i!=j) add_edge(idx[i],idx[j]);
        break;
      }
    }
  }
}

void linky() {
  sort(idy+1,idy+cnty+1,cmpy);
  for (ri i=1;i<=cnty;i++) {
    if (y[idy[i]]==y[idy[i+1]]) add_edge(idy[i],idy[i+1]);
    else {
      for (ri j=i;;j--) if (y[idy[j]]==y[idy[i]] && y[idy[j-1]]!=y[idy[i]]) 
      {
        if (i!=j) add_edge(idy[i],idy[j]);
        break;
      }
    }
  }
}

int prex(int i){
  if (x[idx[i-1]]==x[idx[i]]) return i-1;
  for (ri j=i;;j++) if (x[idx[j]]==x[idx[i]]&&x[idx[j+1]]!=x[idx[i]]) return j;
}

void linkx2() {
  sort(idx+1,idx+cntx+1,cmpx);
  for (ri i=1;i<=cntx;i++) if (t[idx[i]]==1) {
    ri j=prex(i);
    while (t[idx[j]]!=1) {
      add_edge(idx[i],idx[j]);
      j=prex(j);
    }
  }
}


int prey(int i){
  if (y[idy[i-1]]==y[idy[i]]) return i-1;
  for (ri j=i;;j++) if (y[idy[j]]==y[idy[i]]&&y[idy[j+1]]!=y[idy[i]]) return j;
}

void linky2() {
  sort(idy+1,idy+cnty+1,cmpy);
  for (ri i=1;i<=cnty;i++) if (t[idy[i]]==2) {
    ri j=prey(i);
    while (t[idy[j]]!=2) {
      add_edge(idy[i],idy[j]);
      j=prey(j);
    }
  }
}

void tarjan(int x) {
  dfn[x]=low[x]=++tot; inq[x]=1; stk[++top]=x;
  for (ri i=0,l=to[x].size();i<l;i++) {
    int y=to[x][i];
    if (dfn[y] && !inq[y]) continue;
    if (!dfn[y]) {
      tarjan(y);
      low[x]=min(low[x],low[y]);
    }
    else {
      low[x]=min(low[x],dfn[y]);
    }
  }
  if (low[x]==dfn[x]) {
    ++cc;
    int t;
    do {
      t=stk[top];
      inq[t]=0;
      bel[t]=cc;
      top--;
    }
    while (t!=x);
  }
}

void makegraph() {
  for (ri i=1;i<=n;i++) val[bel[i]]++;
  int l=e.size();
  for (ri i=0;i<l;i++) 
    if (bel[e[i].first]!=bel[e[i].second]) about[bel[e[i].first]].push_back(bel[e[i].second]);
}

void dp(int x) {
  if (f[x]!=-1) return;
  f[x]=0;
  for (ri i=0,l=about[x].size();i<l;i++) {
    int y=about[x][i];
    dp(y);
    if (f[y]>f[x]) f[x]=f[y];
  }
  f[x]+=val[x];
}

int main(){
  scanf("%d %d %d",&n,&r,&c);
  
  for (ri i=1;i<=n;i++) {
    scanf("%d %d %d",&x[i],&y[i],&t[i]);
    ot[make_pair(x[i],y[i])]=i;
  }
  
  for (ri i=1;i<=n;i++) {
    if (t[i]==1) {
      idx[++cntx]=i;
    }
    else if (t[i]==2) {
      idy[++cnty]=i;
    }
    else if (t[i]==3) {
      for (ri j=0;j<8;j++) {
        int nx=x[i]+dx[j],ny=y[i]+dy[j];
        if (ot.count(make_pair(nx,ny))) add_edge(i,ot[make_pair(nx,ny)]);
      }
    }
  }
  
  linkx();
  linky();
  
  for (ri i=1;i<=n;i++) {
    if (t[i]==1 || t[i]==3) {
      idy[++cnty]=i;
    }
    if (t[i]==2 || t[i]==3) {
      idx[++cntx]=i;
    }
  }
  linkx2();
  linky2();
  for (ri i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
  makegraph();
  memset(f,-1,sizeof(f));
  int ans=0;
  for (ri i=1;i<=cc;i++) {
    dp(i);
    if (f[i]>ans) ans=f[i];
  }
  cout<<ans<<endl;
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11277926.html