【Luogu】P2403所驼门王的宝藏(强连通分量)
2024-09-03 10:13:11
想到缩点后DP这题就迷之好做
横天门就点向该行连一条边
纵门就点向该列连一条边
ziyou门直接枚举……map搞搞……话说ziyou门为啥是违规内容不让我发布?
然后缩点,DP,1A
不过写得迷之心累……想装死……
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cstdlib>
#include<map>
#define maxn 2200010
#define maxd 100020
#define base r+c
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int dfn[maxn],cnt;
int stack[maxn],top;
int col[maxn],ID;
bool vis[maxn];
int low[maxn];
int size[maxn],sum[maxn];
bool ext[maxn];
int n,r,c; int ans; struct Pic{
struct Edge{
int next,to;
}edge[maxn*];
int head[maxn],num;
Pic(){memset(head,,sizeof(head));}
inline void add(int from,int to){
edge[++num]=(Edge){head[from],to};
head[from]=num;
}
void tarjan(int x){
//printf("%d\n",x);
dfn[x]=low[x]=++cnt;
vis[x]=; stack[++top]=x;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(dfn[to]==){
tarjan(to);
low[x]=min(low[x],low[to]);
}
else if(vis[to]) low[x]=min(low[x],dfn[to]);
}
if(low[x]==dfn[x]){
col[x]=++ID; vis[x]=;
if(x>base) size[ID]++;
while(stack[top]!=x){
col[stack[top]]=ID;
vis[stack[top]]=;
if(stack[top]>base) size[ID]++;
top--;
}
top--;
}
}
void dfs(int x){
vis[x]=;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(vis[to]){
sum[x]=max(sum[x],sum[to]);
continue;
}
dfs(to);
sum[x]=max(sum[x],sum[to]);
}
sum[x]+=size[x];
ans=max(ans,sum[x]);
return;
}
}Old,New; map<long long,int>d; inline long long calc(long long i,long long j){ return (i-)*c+j+base; } struct Node{
int x,y,id,opt;
}q[maxd]; int u[]={,-,-,,,,,,-};
int w[]={,,,,,,-,-,-}; int main(){
n=read(),r=read(),c=read();
for(int i=;i<=n;++i){
int x=read(),y=read(),opt=read();
long long now=calc(x,y);
ext[x]=ext[y+r]=ext[i+base]=;
Old.add(x,i+base);
Old.add(y+r,i+base);
q[i]=(Node){x,y,i+base,opt};
d[now]=i+base;
}
for(int i=;i<=n;++i){
int opt=q[i].opt;
if(opt==) Old.add(q[i].id,q[i].x);
else if(opt==) Old.add(q[i].id,q[i].y+r);
else{
for(int j=;j<;++j){
int x=q[i].x+u[j],y=q[i].y+w[j];
if(x<||x>r||y<||y>c) continue;
if(d.count(calc(x,y))) Old.add(q[i].id,d[calc(x,y)]);
}
}
}
for(int i=;i<=n+base;++i)
if(ext[i]&&dfn[i]==) Old.tarjan(i);
for(int i=;i<=n+base;++i)
for(int j=Old.head[i];j;j=Old.edge[j].next){
int to=Old.edge[j].to;
if(col[i]==col[to]) continue;
New.add(col[i],col[to]);
}
for(int i=;i<=ID;++i)
if(vis[i]==) New.dfs(i);
printf("%d\n",ans);
return ;
}
最新文章
- SQL温故系列两篇(二)
- Assembly(程序集) 反射和缓存
- Linux中断处理体系结构分析
- Custom-Progress-Dialog-Android
- Linux 网络相关命令
- TCP带外数据读写
- 解决octave for windows安装包无法通过SourceForge下载的问题
- Android系统进程Zygote启动过程的源代码分析
- node.js的一些知识
- os内存使用管理之linux篇
- 从MongoDB的ObjectId中获取时间信息
- JavaScript判断对象类型及节点类型、节点名称和节点值
- gdbserver移植到DM368板子上的过程 以及segment fault problem
- 【Android】详解Android Service
- 翻译:使用红外传感器与Arduino进行简单动作与手势检测
- 【ORACLE】数据库空闲1分钟自动断开
- pThreads线程(三) 线程同步--条件变量
- 对于ElasticSearch与Hadoop是如何互相调用的?
- FlashFXP 4.3.1 注册码
- 有趣的Java之调皮的浮点数