洛咕 P2403 [SDOI2010]所駝門王的寶藏
阿新 • • 發佈:2018-11-10
簡單tarjan。
一行的橫天門如果暴力連邊會被卡成平方,所以只要相鄰兩個橫天門連雙向邊,再隨便選一個橫天門向整行連邊即可。縱寰門同理。ziyou門直接map暴力連邊。
然後tarjan直接dp。
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define il inline #define vd void typedef long long ll; il int gi(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=-1; ch=getchar(); } while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } std::map<std::pair<int,int>,int>M; struct yyb{int x,y,o,i;}s[100010]; int fir[100010],dis[1000010],nxt[1000010],id; il vd link(int a,int b){nxt[++id]=fir[a],fir[a]=id,dis[id]=b;} il bool cmp1(const yyb&a,const yyb&b){ if(a.x!=b.x)return a.x<b.x; else return a.o==1; } il bool cmp2(const yyb&a,const yyb&b){ if(a.y!=b.y)return a.y<b.y; else return a.o==2; } const int dX[]={1,1,1,0,0,-1,-1,-1},dY[]={1,0,-1,1,-1,1,0,-1}; int dfn[100010],low[100010],stk[100010],top,ins[100010],scc[100010],w[100010]; std::vector<int>S[100010]; il vd tarjan(int x){ dfn[x]=low[x]=++dfn[0];stk[++top]=x;ins[x]=1; for(int i=fir[x];i;i=nxt[i]) if(!dfn[dis[i]])tarjan(dis[i]),low[x]=std::min(low[x],low[dis[i]]); else if(ins[dis[i]])low[x]=std::min(low[x],dfn[dis[i]]); if(dfn[x]==low[x]){ ++scc[0]; while(stk[top+1]!=x)ins[stk[top]]=0,scc[stk[top]]=scc[0],S[scc[0]].push_back(stk[top]),--top; } } int f[100010]; il int dp(int x){ if(f[x])return f[x]; for(int i=0;i<S[x].size();++i) for(int j=fir[S[x][i]];j;j=nxt[j]) if(scc[dis[j]]!=x) f[x]=std::max(f[x],dp(scc[dis[j]])); return f[x]=f[x]+S[x].size(); } int main(){ #ifndef ONLINE_JUDGE freopen("2403.in","r",stdin); freopen("2403.out","w",stdout); #endif int n=gi(),r=gi(),c=gi(); for(int i=1;i<=n;++i)s[i].x=gi(),s[i].y=gi(),s[i].o=gi(),s[i].i=i,M[std::make_pair(s[i].x,s[i].y)]=i; int lst; std::sort(s+1,s+n+1,cmp1); lst=0; for(int i=1;i<=n;++i){ if(s[i].o==1){ if(s[lst].x==s[i].x)link(s[lst].i,s[i].i),link(s[i].i,s[lst].i); lst=i; }else if(s[lst].x==s[i].x)link(s[lst].i,s[i].i); } std::sort(s+1,s+n+1,cmp2); lst=0; for(int i=1;i<=n;++i){ if(s[i].o==2){ if(s[lst].y==s[i].y)link(s[lst].i,s[i].i),link(s[i].i,s[lst].i); lst=i; }else if(s[lst].y==s[i].y)link(s[lst].i,s[i].i); } for(int i=1;i<=n;++i) if(s[i].o==3) for(int j=0;j<8;++j){ std::pair<int,int>a=std::make_pair(s[i].x+dX[j],s[i].y+dY[j]); if(M.find(a)!=M.end())link(s[i].i,M[a]); } for(int i=1;i<=n;++i)if(!dfn[i])tarjan(i); int ans=0; for(int i=1;i<=scc[0];++i)ans=std::max(ans,dp(i)); printf("%d\n",ans); return 0; }