【刷题】BZOJ 1924 [Sdoi2010]所驼门王的宝藏
Description
Input
第一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“自 由 门”。 保证 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 1
Sample Output
9
HINT
测试点编号 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
Solution
先考虑最朴素的方法,对于一个宝藏,从它向所有它能到达的点连有向边。于是得到了一个有向有环图,对这个图进行缩点,于是得到一个DAG,我们想要的答案就可以在这个DAG上dp求得
但是这样的边数是 \(O(n^2)\) 的,承受不了。于是考虑对于每一行和每一列建一个超级点,这个超级点可以到达当前列的所有宝藏点。而对于一个宝藏,如果它是第一种门,则将它向它所在的行的超级点连边,第二种门同理,第三种门就直接连能到达的宝藏。这样就把边数降了下来,可以承受
需要注意的是,这种缩完点后还要dp的问题,重新建边的时候要注意重边的问题
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=2100000+10,MAXM=1000000+10,MAXD=100000+10;
int n,r,c,e,snt,cnt,Be[MAXN],DFN[MAXN],LOW[MAXN],f[MAXN],in[MAXN],beg[MAXN],ans,to[MAXM<<1],nex[MAXM<<1],Visit_Num,Stack[MAXN],Stack_Num,In_Stack[MAXN],val[MAXN],dr[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
struct node{
int x,y,t;
};
node type[MAXD];
struct edge{
int u,v;
inline bool operator < (const edge &A) const {
return u<A.u||(u==A.u&&v<A.v);
};
inline bool operator == (const edge &A) const {
return u==A.u&&v==A.v;
};
};
edge side[MAXM];
std::queue<int> q;
std::map<int,int> M;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline int id(int x,int y)
{
return (x-1)*c+y;
}
inline void insert(int x,int y,int opt=1)
{
if(opt)side[++snt]=(edge){x,y};
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void Tarjan(int x)
{
DFN[x]=LOW[x]=++Visit_Num;
In_Stack[x]=1;
Stack[++Stack_Num]=x;
for(register int i=beg[x];i;i=nex[i])
if(!DFN[to[i]])Tarjan(to[i]),chkmin(LOW[x],LOW[to[i]]);
else if(In_Stack[to[i]]&&DFN[to[i]]<LOW[x])LOW[x]=DFN[to[i]];
if(LOW[x]==DFN[x])
{
int temp;++cnt;
do{
temp=Stack[Stack_Num--];
In_Stack[temp]=0;
Be[temp]=cnt;
val[cnt]+=(temp<=n?1:0);
}while(temp!=x);
}
}
inline void toposort()
{
for(register int i=1;i<=cnt;++i)
if(!in[i])q.push(i),f[i]=val[i];
while(!q.empty())
{
int x=q.front();
q.pop();
for(register int i=beg[x];i;i=nex[i])
{
chkmax(f[to[i]],f[x]+val[to[i]]);
in[to[i]]--;
if(!in[to[i]])q.push(to[i]);
}
}
}
int main()
{
read(n);read(r);read(c);
for(register int i=1;i<=n;++i)
{
int x,y,t;read(x);read(y);read(t);
insert(x+n,i);insert(y+r+n,i);
M[id(x,y)]=i;
type[i]=(node){x,y,t};
}
for(register int i=1;i<=n;++i)
{
int x=type[i].x,y=type[i].y,t=type[i].t;
if(t==1)insert(i,x+n);
if(t==2)insert(i,y+r+n);
if(t==3)
for(register int k=0;k<8;++k)
{
int dx=x+dr[k][0],dy=y+dr[k][1];
if(M[id(dx,dy)])insert(i,M[id(dx,dy)]);
}
}
for(register int i=1;i<=n+r+c;++i)
if(!DFN[i])Tarjan(i);
e=0;memset(beg,0,sizeof(beg));
for(register int i=1;i<=snt;++i)side[i].u=Be[side[i].u],side[i].v=Be[side[i].v];
std::sort(side+1,side+snt+1);
snt=std::unique(side+1,side+snt+1)-side-1;
for(register int i=1;i<=snt;++i)
if(side[i].u!=side[i].v)insert(side[i].u,side[i].v,0),in[side[i].v]++;
toposort();
for(register int i=1;i<=cnt;++i)chkmax(ans,f[i]);
write(ans,'\n');
return 0;
}
【刷题】BZOJ 1924 [Sdoi2010]所驼门王的宝藏的更多相关文章
- [BZOJ 1924][Sdoi2010]所驼门王的宝藏
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1285 Solved: 574[Submit][Sta ...
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...
- bzoj 1924 [Sdoi2010]所驼门王的宝藏(构图,SCC,DP)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
[题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...
- [LuoguP2403][SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- [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 ...
随机推荐
- UDP穿越NAT原理(p2p)
转载自:http://blog.csdn.net/ldd909/article/details/5979967 论坛上经常有对P2P原理的讨论,但是讨论归讨论,很少有实质的东西产生(源代码).在这里我 ...
- linux中原子操作实现方式
原子操作提供了指令原子执行,中间没有中断.就像原子被认为是不可分割颗粒一样,原子操作(atomic operation)是不可分割的操作. 如下面简单的例子: Thread 1 ...
- python基础1之python介绍、安装、变量和字符编码、数据类型、输入输出、数据运算、循环
开启python之路 内容概要: 一.python介绍 二.安装 三.第一个python程序 四.变量和字符编码 五.用户输入 六.数据类型 七.一切皆对象 八.数据运算 九.if else 流程判断 ...
- 20155218《网络对抗》MSF基础应用
20155218<网络对抗>MSF基础应用 实验过程 1.一个主动攻击实践,如ms08_067; 首先使用 search ms08_067查询一下该漏洞: show target 查看可以 ...
- 2017-2018-1 20155232 嵌入式C语言——时钟
2017-2018-1 20155232 嵌入式C语言--时钟 任务: 在作业本上完成附图作业,要认真看题目要求. 提交作业截图 作弊本学期成绩清零(有雷同的,不管是给别人传答案,还是找别人要答案都清 ...
- 在ListBoxItem的样式中的button传参,把当前选中项传递到命令的方法
原文:在ListBoxItem的样式中的button传参,把当前选中项传递到命令的方法 前端页面: <Style x:Key="ThumbItemStyle" TargetT ...
- mfc 虚函数
知识点 类虚函数概念 类虚函数定义virtual 一.虚函数 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数. 二.虚函数定义 定义:在某基类中声明为 virtual 并在一个或多个派 ...
- win10+anaconda3+python3.6+opencv3.1.0
最近用windows系统比较多,就想在win10下搞一下深度学习这一方面的研究,那么就需要配置好环境巴拉巴拉的一堆东西.默默记个笔记,正所谓“好记性不如烂笔头”. 1.安装Anaconda 这个是一个 ...
- 微信小程序获取客户端系统信息
微信小程序中有个API: wx.getSystemInfo() 可以获取系统的信息 wx.getSystemInfoSync()===>同步获取系统信息 wx.getSyatemInfo({ s ...
- C#_正则表达式
概述 正则表达式,主要是用符号描述了一类特定的文本(模式).而正则表达式引擎则负责在给定的字符串中,查找到这一特定的文本. 本文主要是列出常用的正则表达式符号,加以归类说明.本文仅仅是快速理解了正则表 ...