这道题苟了我好久,因为链表的内存问题,之后再细讲。
首先这是一道Tarjan+DAG上DP的题目。
有三种门,对于每种门可以和其他门相连。即连边。
使用链表快速查询连边。
建完图后可以进行Tarjan缩点。
然后做一遍DAG上DP就好了。(记搜)
然后因为建图时会有很多条边,而行列最多只有100000个,所以要分开定义。
不然会爆内存。
code:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int read() { char c;while(c=getchar(),c<'0'||c>'9'); int x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0'; return x; } int N,R,C,x,y,fx,fy,o,a[100005][4]; struct list{ int head[4000005],nxt[4000005],To[4000005],cnt; list(){memset(head,-1,sizeof head);memset(nxt,-1,sizeof nxt);} void add(int x,int y){ To[cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; cnt++; } }M,NM; struct list2{ int head[100005],nxt[100005],To[100005],cnt; list2(){memset(head,-1,sizeof head);memset(nxt,-1,sizeof nxt);} void add(int x,int y){ To[cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; cnt++; } }A,B; int DFN[100005],LOW[100005],stack[100005],top,cnt,vis[100005],fa[100005]; int otk[100005],f[100005],sk[100005],ans; void tarjan(int now) { stack[++top]=now; DFN[now]=LOW[now]=++cnt; vis[now]=1; for(int i=M.head[now];i!=-1;i=M.nxt[i]){ if(!DFN[M.To[i]])tarjan(M.To[i]),LOW[now]=min(LOW[now],LOW[M.To[i]]); else if(vis[M.To[i]])LOW[now]=min(LOW[now],DFN[M.To[i]]); } if(DFN[now]==LOW[now]){ while(stack[top]!=now) fa[stack[top]]=now,sk[now]++,vis[stack[top]]=0,top--; fa[stack[top]]=now; sk[now]++; vis[stack[top--]]=0; } return ; } int dfs(int now) { if(vis[now])return f[now]; vis[now]=1; for(int i=NM.head[now];i!=-1;i=NM.nxt[i]){ f[now]=max(f[now],dfs(NM.To[i])); } f[now]+=sk[now]; ans=max(ans,f[now]); return f[now]; } int main() { N=read(),R=read(),C=read(); register int i,j,k; for(i=1;i<=N;i++){ a[i][1]=read(),a[i][2]=read(),a[i][3]=read(); A.add(a[i][1],i);B.add(a[i][2],i); } for(i=1;i<=N;i++){ x=a[i][1],y=a[i][2],o=a[i][3]; if(o==1) for(j=A.head[x];j!=-1;j=A.nxt[j]) if(A.To[j]!=i)M.add(i,A.To[j]); if(o==2) for(j=B.head[y];j!=-1;j=B.nxt[j]) if(B.To[j]!=i)M.add(i,B.To[j]); if(o==3){ for(k=-1;k<2;k++) for(j=A.head[x+k];j!=-1;j=A.nxt[j]){ fx=a[A.To[j]][1],fy=a[A.To[j]][2]; if(fx<=x+1&&fx>=x-1&&fy<=y+1&&fy>=y-1&&A.To[j]!=i) M.add(i,A.To[j]); } } } for(i=1;i<=N;i++)if(!DFN[i])tarjan(i); memset(vis,0,sizeof vis); for(i=1;i<=N;i++){ if(!vis[i]){vis[i]=1; for(j=M.head[i];j!=-1;j=M.nxt[j]){ if(fa[M.To[j]]!=fa[i]) otk[fa[M.To[j]]]++; } } } for(i=1;i<=N;i++) for(j=M.head[i];j!=-1;j=M.nxt[j]) if(fa[i]!=fa[M.To[j]])NM.add(fa[i],fa[M.To[j]]); memset(vis,0,sizeof vis); for(i=1;i<=N;i++) if(!otk[fa[i]]&&!vis[fa[i]]) dfs(i); printf("%d",ans); return 0; }