[BZOJ 1924][Sdoi2010]所驼门王的宝藏
1924: [Sdoi2010]所驼门王的宝藏
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 1285 Solved: 574
[Submit][Status][Discuss]Description
Input
第一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“自由<x>门”。 保证 1≤xi≤R,1≤yi≤C,所有的传送门位置互不相同。
Output
只有一个正整数,表示你确定的路线所经过不同藏宝宫室的最大数目。
Sample Input
10 7 7
2 2 1
2 4 2
1 7 2
2 7 3
4 2 2
4 4 1
6 7 3
7 7 1
7 5 2
5 2 1Sample Output
9HINT
测试点编号 N R C 1 16 20 20 2 300 1,000 1,000 3 500 100,000 100,000 4 2,500 5,000 5,000 5 50,000 5,000 5,000 6 50,000 1,000,000 1,000,000 7 80,000 1,000,000 1,000,000 8 100,000 1,000,000 1,000,000 9 100,000 1,000,000 1,000,000 10 100,000 1,000,000 1,000,000
Source
题解
按照题意建好有向边, 跑一遍 $Tarjan$ 缩成 $DAG$ 之后直接 $O(n)$ $DP$ 一遍求最大值即可.
至于快速建边, 可以用 $std::set$ 维护同一行/同一列的所有节点编号, 二维 $std::map$ 维护各个节点的位置. 不过如果所有点都在同一行的话可能会$GG$
参考代码
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> const int MAXV=1e5+;
const int MAXE=5e6; struct Edge{
int from;
int to;
Edge* next;
};
Edge E[MAXE];
Edge* head[MAXV];
Edge* top=E; struct Node{
int x;
int y;
int type;
};
Node N[MAXV]; int v;
int c;
int r;
int ans;
int clk;
int scc;
int dp[MAXV];
int dfn[MAXV];
int low[MAXV];
int size[MAXV];
int belong[MAXV]; bool inStack[MAXV]; std::stack<int> s;
std::map< int, std::set<int> > sx,sy;
std::map< int, std::map<int,int> > m; void Build();
void DFS(int);
void Tarjan(int);
void SweepEdge();
void Initialize();
void Insert(int,int); int main(){
Initialize();
Build();
for(int i=;i<=v;i++){
if(dfn[i]==)
Tarjan(i);
}
SweepEdge();
for(int i=;i<=v;i++){
if(dp[i]==)
DFS(i);
}
printf("%d\n",ans);
return ;
} void Initialize(){
scanf("%d%d%d",&v,&r,&c);
for(int i=;i<=v;i++){
scanf("%d%d%d",&N[i].x,&N[i].y,&N[i].type);
sx[N[i].x].insert(i);
sy[N[i].y].insert(i);
(m[N[i].x])[N[i].y]=i;
}
} void DFS(int root){
if(dp[root]!=)
return;
else{
dp[root]=size[root];
int max=;
for(Edge* i=head[root];i!=NULL;i=i->next){
DFS(i->to);
max=std::max(max,dp[i->to]);
}
dp[root]+=max;
ans=std::max(dp[root],ans);
}
} void SweepEdge(){
// puts("SE");
Edge* ed=top;
top=E;
memset(head,,sizeof(head));
for(Edge* i=E;i!=ed;i++){
if(belong[i->from]!=belong[i->to])
Insert(belong[i->from],belong[i->to]);
}
} void Tarjan(int root){
dfn[root]=low[root]=++clk;
inStack[root]=true;
s.push(root);
for(Edge* i=head[root];i!=NULL;i=i->next){
if(dfn[i->to]==){
Tarjan(i->to);
low[root]=std::min(low[root],low[i->to]);
}
else if(inStack[i->to]){
low[root]=std::min(low[root],dfn[i->to]);
}
}
if(dfn[root]==low[root]){
scc++;
int top;
do{
top=s.top();
inStack[top]=false;
size[scc]++;
belong[top]=scc;
s.pop();
}while(top!=root);
}
} void Build(){
for(int k=;k<=v;k++){
if(N[k].type==){
std::map< int, std::set<int> >::iterator px=sx.find(N[k].x);
for(std::set<int>::iterator i=(*px).second.begin();i!=(*px).second.end();++i){
if(k!=*i)
Insert(k,*i);
}
}
else if(N[k].type==){
std::map< int, std::set<int> >::iterator py=sy.find(N[k].y);
for(std::set<int>::iterator i=(*py).second.begin();i!=(*py).second.end();++i){
if(k!=*i)
Insert(k,*i);
}
}
else if(N[k].type==){
for(int dx=-;dx<=;dx++){
for(int dy=-;dy<=;dy++){
if(dx!=||dy!=){
int tmp=m[N[k].x+dx][N[k].y+dy];
if(tmp!=&&tmp!=k){
Insert(k,tmp);
}
}
}
}
}
}
} inline void Insert(int from,int to){
// printf("Insert %d to %d\n",from,to);
top->from=from;
top->to=to;
top->next=head[from];
head[from]=top++;
}
Backup

[BZOJ 1924][Sdoi2010]所驼门王的宝藏的更多相关文章
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...
- bzoj 1924 [Sdoi2010]所驼门王的宝藏(构图,SCC,DP)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- 【刷题】BZOJ 1924 [Sdoi2010]所驼门王的宝藏
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
[题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...
- [SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- [LuoguP2403][SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- 洛谷 2403 [SDOI2010] 所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐, ...
- Luogu 2403 [SDOI2010]所驼门王的宝藏
BZOJ 1924 内存要算准,我MLE了两次. 建立$n + r + c$个点,对于一个点$i$的坐标为$(x, y)$,连边$(n + x, i)$和$(n + r + y, i)$,代表这一列和 ...
- BZOJ 1924 && Luogu P2403 [SDOI2010]所驼门王的宝藏 恶心建图+缩点DP
记住:map一定要这么用: if(mp[x[i]+dx[j]].find(y[i]+dy[j])!=mp[x[i]+dx[j]].end()) add(i,mp[x[i]+dx[j]][y[i]+dy ...
随机推荐
- IOS使用Auto Layout中的VFL适配
做登录页面,之前做都是用frame做,今天想着用Auto Layout中的VFL来做.觉得做的效果还是可以的(自恋一下下). 首先看下效果图和标记图 自己在做的过程中也遇到了好多问题,不过也一个一个的 ...
- laravel数据迁移
创建数据库迁移: php artisan make:migration create_表名_table 回车后就会创建迁移版本 回滚数据库迁移: php artisan migrate 会将数据按 ...
- 打印插件--PAZU
PAZU对打印控制实现了: 2.1 设置页眉页脚 2.2 指定纸张大小 2.3 设置纸张方向 2.4 设置页边距 2.5 选择指定的打印机 2.6 无需用户确认,JS直接调用打印预览 2.7 无需用户 ...
- 题解 P1068 【分数线划定】
由于涉及到排序和对应序号 那就定义一个结构体 结合STL模板中的sort日常沉迷sort 提示:虽然我也是蒟弱 sort是快速排序函数,有两个或三个参数, 两个参数适用于平常的数字类型,即形sort( ...
- 《JavaWeb从入门到改行》多重外键关系在java中的处理方案
目录:(点击红色方框展开子目录) 问题描述 无 项目案例说明 业务描述 数据库说明 项目源码及下载 无 问题描述 如上两图,数据库中各个表之间有很多的外键关系,其中业务关系是一个用户下有该用户的订单, ...
- html5 转义实体字符 元数据 跳转 全局属性 id class lang style
实体 Html 实体就是把特殊字符通过代码显示出来, 比如, <>在浏览器会识别为标签,不能正常显示, 这是你就需要安如<去表达左尖括号. 元数据 2. 声明字符编码 3.模 ...
- JS读取本地IP地址信息
HTML <div> <p>点击下面的按钮,查看本地IP信息</p> <span class="span">点击查看</spa ...
- Difference between scipy.fftpack and numpy.fft
scipy.fftpack 和 numpy.fft 的区别 When applying scipy.fftpack.rfft and numpy.fft.rfft I get the followin ...
- LDAP常用命令解析
OpenLDAP常用命令讲解: ldapadd -x 进行简单认证 -D 用来绑定服务器的DN -h 目录服务的地址 -w 绑定DN的密码 ...
- 实验吧Crypto题目Writeup
这大概是一篇不怎么更新的没什么用的网上已经有了很多差不多的东西的博客. 变异凯撒 忘记了2333 传统知识+古典密码 先查百度百科,把年份变成数字,然后猜测+甲子的意思,一开始以为是加1,后来意识到是 ...
