题解:
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;
}