题解:
Trajan缩点+DP最长路
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int maxn=1000009; int n,r,c; int ans; vector<int>dx[maxn]; vector<int>dy[maxn]; int inx[maxn],iny[maxn],inz[maxn]; vector<int>G1[maxn]; vector<int>G2[maxn]; int dfsclock,scccnt; int pre[maxn],lowlink[maxn],sccno[maxn]; int Sta[maxn],top; int Dfs(int u){ pre[u]=lowlink[u]=(++dfsclock); Sta[++top]=u; for(int i=0;i<G1[u].size();++i){ int v=G1[u][i]; if(!pre[v]){ Dfs(v); lowlink[u]=min(lowlink[u],lowlink[v]); }else if(!sccno[v]){ lowlink[u]=min(lowlink[u],pre[v]); } } if(lowlink[u]==pre[u]){ ++scccnt; for(;;){ int x=Sta[top--]; sccno[x]=scccnt; if(x==u)break; } } } int v[maxn]; int Trajan(){ for(int i=1;i<=n;++i){ if(!pre[i])Dfs(i); } for(int i=1;i<=n;++i){ v[sccno[i]]++; for(int j=0;j<G1[i].size();++j){ if(sccno[i]!=sccno[G1[i][j]]){ G2[sccno[i]].push_back(sccno[G1[i][j]]); } } } } int f[maxn]; int dp(int x){ if(f[x])return 0; for(int i=0;i<G2[x].size();++i){ dp(G2[x][i]); f[x]=max(f[x],f[G2[x][i]]); } f[x]+=v[x]; } int abs(int x){ if(x<0)return -x; else return x; } int minit(){ top=dfsclock=scccnt=ans=0; memset(f,0,sizeof(f)); memset(v,0,sizeof(v)); memset(pre,0,sizeof(pre)); memset(lowlink,0,sizeof(lowlink)); memset(sccno,0,sizeof(sccno)); for(int i=0;i<=max(r,c)+1;++i){ dx[i].clear();dy[i].clear();G1[i].clear();G2[i].clear(); } } int main(){ scanf("%d%d%d",&n,&r,&c); //minit(); for(int i=1;i<=n;++i){ scanf("%d%d%d",&inx[i],&iny[i],&inz[i]); dx[inx[i]].push_back(i); dy[iny[i]].push_back(i); } for(int i=1;i<=n;++i){ if(inz[i]==1){ for(int j=0;j<dx[inx[i]].size();++j){ G1[i].push_back(dx[inx[i]][j]); } } if(inz[i]==2){ for(int j=0;j<dy[iny[i]].size();++j){ G1[i].push_back(dy[iny[i]][j]); } } if(inz[i]==3){ for(int j=0;j<dx[inx[i]-1].size();++j){ if(abs(iny[dx[inx[i]-1][j]]-iny[i])<=1){ G1[i].push_back(dx[inx[i]-1][j]); } } for(int j=0;j<dx[inx[i]].size();++j){ if(abs(iny[dx[inx[i]][j]]-iny[i])==1){ G1[i].push_back(dx[inx[i]][j]); } } for(int j=0;j<dx[inx[i]+1].size();++j){ if(abs(iny[dx[inx[i]+1][j]]-iny[i])<=1){ G1[i].push_back(dx[inx[i]+1][j]); } } } } Trajan(); for(int i=1;i<=n;++i){ dp(i); ans=max(ans,f[i]); } printf("%d\n",ans); return 0; }