SDOI2010所驼门王的宝藏
Posted shxnb666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDOI2010所驼门王的宝藏相关的知识,希望对你有一定的参考价值。
题面
https://www.luogu.org/problem/P2403
题解
#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;
以上是关于SDOI2010所驼门王的宝藏的主要内容,如果未能解决你的问题,请参考以下文章