题目链接:右转进入题目
题目大意:自行参考题目
题解:tarjan缩点后拓排一下dp乱搞即可。
代码:
//BZOJ 1924
//SDOI 2010
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<algorithm>
#define MAXN 100010
#define MAXRC 1000010
using namespace std;
vector<int> vx[MAXRC],vy[MAXRC],g[MAXN],sccg[MAXN];
int n,r,c,color_cnt,belong[MAXN],w[MAXN],sz[MAXN];
int dp[MAXN],x[MAXN],y[MAXN],t[MAXN],topo[MAXN];
void add_edge(int u,int v)
{
g[u].push_back(v);return;
}
int state[MAXN],low[MAXN],dfn[MAXN],dfs_clock;
stack<int> s;
queue<int> q;
int dfs(int x)
{
state[x]=1;
low[x]=dfn[x]=++dfs_clock;
s.push(x);
for(int i=g[x].size()-1;i>=0;i--)
if(!state[g[x][i]])
{
dfs(g[x][i]);
low[x]=min(low[x],low[g[x][i]]);
}
else if(state[g[x][i]]==1)
low[x]=min(low[x],dfn[g[x][i]]);
if(dfn[x]==low[x])
{
color_cnt++;
sz[color_cnt]=0;
while(s.top()!=x)
{
sz[color_cnt]++;
belong[s.top()]=color_cnt;
state[s.top()]=2;s.pop();
}
belong[s.top()]=color_cnt;
state[s.top()]=2;s.pop();
sz[color_cnt]++;
}
return 0;
}
void clears(stack<int> &s)
{
while(!s.empty()) s.pop();
return;
}
int main()
{
scanf("%d%d%d",&n,&r,&c);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&x[i],&y[i],&t[i]);
vx[x[i]].push_back(i);
vy[y[i]].push_back(i);
}
/* for(int i=1;i<=c;i++)
{
cout<<i<<"::";
for(int j=vy[i].size()-1;j>=0;j--)
cout<<vy[i][j]<<" ";
cout<<endl;
}*/
for(int i=1;i<=n;i++)
if(t[i]==1)
for(int j=vx[x[i]].size()-1;j>=0;j--)
{
if(i!=vx[x[i]][j])
add_edge(i,vx[x[i]][j]);
}
else if(t[i]==2)
for(int j=vy[y[i]].size()-1;j>=0;j--)
{
if(i!=vy[y[i]][j])
add_edge(i,vy[y[i]][j]);
}
else for(int j=-1;j<=1;j++)
if(x[i]+j>=1&&x[i]+j<=r)
for(int k=vx[x[i]+j].size()-1;k>=0;k--)
if(abs(y[vx[x[i]+j][k]]-y[i])<=1&&vx[x[i]+j][k]!=i)
add_edge(i,vx[x[i]+j][k]);
clears(s);dfs_clock=color_cnt=0;
for(int i=1;i<=n;i++)
if(!state[i]) dfs(i);
for(int i=1;i<=n;i++)
for(int j=g[i].size()-1;j>=0;j--)
if(belong[i]!=belong[g[i][j]])
{
sccg[belong[i]].push_back(belong[g[i][j]]);
w[belong[g[i][j]]]++;
}
int scc_cnt=color_cnt;
for(int i=1;i<=scc_cnt;i++)
if(w[i]==0) q.push(i);
int cnt=0,x;
while(!q.empty())
{
topo[++cnt]=x=q.front();q.pop();
for(int i=sccg[x].size()-1;i>=0;i--)
{
w[sccg[x][i]]--;
if(!w[sccg[x][i]]) q.push(sccg[x][i]);
}
}
int maxans=0;
for(int i=1;i<=scc_cnt;i++)
{
dp[topo[i]]+=sz[topo[i]];
if(dp[topo[i]]>maxans) maxans=dp[topo[i]];
for(int j=sccg[topo[i]].size()-1;j>=0;j--)
dp[sccg[topo[i]][j]]=max(dp[sccg[topo[i]][j]],dp[topo[i]]);
}
printf("%d\n",maxans);return 0;
}