给出一个
1
e
6
∗
1
e
6
1e6*1e6
1e6∗1e6的矩形,矩形中有三种传送门,分别是传送这一行的任意一个传送门,或者传送到这一列的任意一个传送门,或者是传送附近
8
8
8个位置的任意一个传送门。然后你可以选择并且只能选择从任何一个传送门进入,从任何一个传送门出来。求经过最多的点的个数是多少。
预处理所有的点,然后直接连边。tarjan缩环之后跑spfa或者拓扑排序都可以。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=1e5+7;
const int M=1e6+7;
int n,r,c;
int x[N],y[N],t[N];
map< pair<int,int>,int >mp;
vector<int> R[M],C[M];
vector<int> G[N];
int dx[]={-1,-1,-1,0,0,1,1,1};
int dy[]={0,-1,1,1,-1,1,0,-1};
void add(int u,int v) {
G[u].push_back(v);
}
int dfn[N],low[N],tim=0;
int s[N],top=0;
bool ins[N];
int bel[N],w[N],scc=0;
void tarjan(int u) {
dfn[u]=low[u]=++tim;
s[++top]=u;
ins[u]=1;
for(int i=0;i<G[u].size();i++) {
int v=G[u][i];
if(!dfn[v]) {
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(ins[v]) {
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]) {
bel[u]=++scc;
ins[u]=0;
w[scc]=1;
while(s[top]!=u) {
bel[s[top]]=scc;
ins[s[top]]=0;
w[scc]++;
top--;
}
top--;
}
}
struct edge{ int v,w; };
vector<edge> go[N];
bool inq[N];
int dis[N];
int spfa(int u) {
int ans=0;
queue<int> q;
q.push(u);
inq[u]=1;
dis[u]=0;
for(int i=1;i<=scc;i++)
dis[i]=0;
while(!q.empty()) {
int u=q.front();
q.pop();
inq[u]=0;
for(int i=0;i<go[u].size();i++) {
int v=go[u][i].v;
int w=go[u][i].w;
if(dis[v]<dis[u]+w) {
dis[v]=dis[u]+w;
ans=max(ans,dis[v]);
if(!inq[v]) {
q.push(v);
inq[v]=1;
}
}
}
}
return ans;
}
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]);
R[x[i]].push_back(i);
C[y[i]].push_back(i);
mp[make_pair(x[i],y[i])]=i;
}
for(int i=1;i<=n;i++) {
if(t[i]==1) {
for(int j=0;j<R[x[i]].size();j++)
add(i,R[x[i]][j]);
}
else if(t[i]==2) {
for(int j=0;j<C[y[i]].size();j++)
add(i,C[y[i]][j]);
}
else if(t[i]==3) {
for(int j=0;j<8;j++) {
int nx=x[i]+dx[j];
int ny=y[i]+dy[j];
if(mp.count(make_pair(nx,ny))) {
add(i,mp[make_pair(nx,ny)]);
}
}
}
}
for(int i=1;i<=n;i++) {
if(!dfn[i]) {
tarjan(i);
}
}
for(int i=1;i<=n;i++) {
for(int j=0;j<G[i].size();j++) {
int u=i;
int v=G[i][j];
if(bel[u]==bel[v]) continue;
go[bel[u]].push_back({bel[v],w[bel[v]]});
}
}
for(int i=1;i<=scc;i++)
go[0].push_back({i,w[i]});
int ans=spfa(0);
printf("%d\n",ans);
return 0;
}