【Luogu】P2403所驼门王的宝藏(强连通分量)
想到缩点后DP这题就迷之好做
横天门就点向该行连一条边
纵门就点向该列连一条边
ziyou门直接枚举……map搞搞……话说ziyou门为啥是违规内容不让我发布?
然后缩点,DP,1A
不过写得迷之心累……想装死……
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<cstdlib> #include<map> #define maxn 2200010 #define maxd 100020 #define base r+c using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } int dfn[maxn],cnt; int stack[maxn],top; int col[maxn],ID; bool vis[maxn]; int low[maxn]; int size[maxn],sum[maxn]; bool ext[maxn]; int n,r,c; int ans; struct Pic{ struct Edge{ int next,to; }edge[maxn*2]; int head[maxn],num; Pic(){memset(head,0,sizeof(head));} inline void add(int from,int to){ edge[++num]=(Edge){head[from],to}; head[from]=num; } void tarjan(int x){ //printf("%d\n",x); dfn[x]=low[x]=++cnt; vis[x]=1; stack[++top]=x; for(int i=head[x];i;i=edge[i].next){ int to=edge[i].to; if(dfn[to]==0){ tarjan(to); low[x]=min(low[x],low[to]); } else if(vis[to]) low[x]=min(low[x],dfn[to]); } if(low[x]==dfn[x]){ col[x]=++ID; vis[x]=0; if(x>base) size[ID]++; while(stack[top]!=x){ col[stack[top]]=ID; vis[stack[top]]=0; if(stack[top]>base) size[ID]++; top--; } top--; } } void dfs(int x){ vis[x]=1; for(int i=head[x];i;i=edge[i].next){ int to=edge[i].to; if(vis[to]){ sum[x]=max(sum[x],sum[to]); continue; } dfs(to); sum[x]=max(sum[x],sum[to]); } sum[x]+=size[x]; ans=max(ans,sum[x]); return; } }Old,New; map<long long,int>d; inline long long calc(long long i,long long j){ return (i-1)*c+j+base; } struct Node{ int x,y,id,opt; }q[maxd]; int u[9]={0,-1,-1,0,1,1,1,0,-1}; int w[9]={0,0,1,1,1,0,-1,-1,-1}; int main(){ n=read(),r=read(),c=read(); for(int i=1;i<=n;++i){ int x=read(),y=read(),opt=read(); long long now=calc(x,y); ext[x]=ext[y+r]=ext[i+base]=1; Old.add(x,i+base); Old.add(y+r,i+base); q[i]=(Node){x,y,i+base,opt}; d[now]=i+base; } for(int i=1;i<=n;++i){ int opt=q[i].opt; if(opt==1) Old.add(q[i].id,q[i].x); else if(opt==2) Old.add(q[i].id,q[i].y+r); else{ for(int j=1;j<9;++j){ int x=q[i].x+u[j],y=q[i].y+w[j]; if(x<1||x>r||y<1||y>c) continue; if(d.count(calc(x,y))) Old.add(q[i].id,d[calc(x,y)]); } } } for(int i=1;i<=n+base;++i) if(ext[i]&&dfn[i]==0) Old.tarjan(i); for(int i=1;i<=n+base;++i) for(int j=Old.head[i];j;j=Old.edge[j].next){ int to=Old.edge[j].to; if(col[i]==col[to]) continue; New.add(col[i],col[to]); } for(int i=1;i<=ID;++i) if(vis[i]==0) New.dfs(i); printf("%d\n",ans); return 0; }