【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
最开始我想写线段树优化建图的说,数据结构学傻了233
虽然矩阵很大,但是没什么用,真正有用的是那些关键点
考虑关键点的类型:
- 横走型
- 竖走型
- 八连通型
本质上只有两种类型(走一大串/走八连通),我们考虑这样一种建图方法:
- 对于每一行每一列建立一个点(点权为\(0\))
- 对于关键点建立一个点(点权为\(1\))
然后考虑这样一种建图方式,得到一个有点权无边权图
- 关键点所在的行与列无偿地向这个关键点连边
- 横走型的关键点向行连一条边,竖走型同理
- 八连通型直接向周围的关键点连边
题目要求走到的点最多,也就是求一条最长路径,但是显然这个图上可能有正环,但是点权贡献只能算一次,自然想到直接缩点。缩完点后得到一个\(DAG\),直接在这个\(DAG\)上\(dp\)
\(dp_i\)表示从这个节点出发最长的路径,直接转移。
分析点数,显然是\(O(3n)\),分析边数,一个点最多连接十条边,\(tarjin\)是\(O(n)\)的,但是我们用了\(map\)所以复杂度\(O(n\log n)\),实际上,直接用unordered_map
就是\(O(n)\)了,就帅一点...
至于实现,直接用\(map\)存std::pair < int ,int >
就好了
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1e5+5;
struct E{
int to,nx;
E(){to=nx=0;}
E(const int&a,const int&b){to=a;nx=b;}
};
vector < E > e,e2;
pair < int ,int > node[maxn];
int head[maxn*3];
int head2[maxn*3];
int TT[maxn];
int dp[maxn*3];
int n,m,k;
void add2(const int&fr,const int&to){
e2.push_back(E(to,head2[fr]));
head2[fr]=e2.size()-1;
}
void add(const int&fr,const int&to){
e.push_back(E(to,head[fr]));
head[fr]=e.size()-1;
}
int idx[maxn],idy[maxn];
int w[maxn*3];
int stk[maxn*3];
int qaq,top;
int be[maxn*3];
int siz[maxn*3];
int dfn[maxn*3],low[maxn*3],in[maxn*3];
int tim,ans;
int qaqcnt;
int dfs2(const int&now){
if(dp[now]) return dp[now];
register int ret=0;
for(register int t=head2[now];t;t=e2[t].nx)
ret=max(ret,dfs2(e2[t].to));
return dp[now]=ret+siz[now];
}
void dfs(const int&now){
dfn[now]=low[now]=++tim;in[now]=1;stk[++top]=now;
for(register int t=head[now];t;t=e[t].nx){
if(!dfn[e[t].to])
dfs(e[t].to),low[now]=min(low[now],low[e[t].to]);
if(dfn[e[t].to]&&in[e[t].to])
low[now]=min(low[now],dfn[e[t].to]);
}
if(dfn[now]==low[now]){
register int temp=0;
++qaq;
do{
temp=stk[top--];
in[temp]=0;siz[qaq]+=w[temp];
be[temp]=qaq;
}while(temp!=now);
}
}
map < pair < int ,int > , int > s;
inline int init(const int&a,const int&b,const int&c){
e.push_back(E()); e.push_back(E());
e2.push_back(E()); e2.push_back(E());
qaqcnt=k=a;n=b;m=c;
for(register int t=1;t<=k;++t){
register int t1=qr(),t2=qr(),t3=qr();
node[t].first=t1;
node[t].second=t2;
TT[t]=t3; w[t]=1;
s[make_pair(t1,t2)]=t;
if(!idx[t1]) idx[t1]=++qaqcnt;
if(!idy[t2]) idy[t2]=++qaqcnt;
add(idx[t1],t);
add(idy[t2],t);
}
for(register int t=1;t<=k;++t){
if(TT[t]==1) add(t,idx[node[t].first]);
if(TT[t]==2) add(t,idy[node[t].second]);
if(TT[t]==3)
for(register int dx=-1;dx<=1;++dx)
for(register int dy=-1;dy<=1;++dy)
if(dx||dy){
auto f=s.find(make_pair(node[t].first+dx,node[t].second+dy));
if(f!=s.end()) add(t,f->second);
}
}
for(register int t=1;t<=qaqcnt;++t)
if(!dfn[t]) dfs(t);
for(register int t=1;t<=qaqcnt;++t)
for(register int i=head[t];i;i=e[i].nx)
if(be[e[i].to]!=be[t])
add2(be[t],be[e[i].to]);
for(register int t=1;t<=qaq;++t)
ans=max(ans,dfs2(t));
printf("%d\n",ans);
return 0;
}
int main(){
int a=qr(),b=qr(),c=qr();
return init(a,b,c);
}
【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)的更多相关文章
- BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- BZOJ 1924 所驼门王的宝藏(强连通分量缩点+DAG最长链)
思路不是很难,因为宝藏只会在给出的n个点内有,于是只需要在这n个点里面连边,一个点如果能到达另一个点则连一条有向边, 这样用强连通分量缩点后答案就是DAG的最长链. 问题在于暴力建图是O(n^2)的, ...
- 题解 [SDOI2010]所驼门王的宝藏
传送门 保分题再度爆零,自闭ing×2 tarjan没写vis数组,点权算的也有点问题 这题情况3的连边有点麻烦,考场上想了暴力想了二分就是没想到可以直接拿map水过去 不过map果然贼慢,所以这也是 ...
- [BZOJ 1924][Sdoi2010]所驼门王的宝藏
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1285 Solved: 574[Submit][Sta ...
- 洛谷 2403 [SDOI2010] 所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐, ...
- [SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- [LuoguP2403][SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...
- 洛谷 P2403 [SDOI2010]所驼门王的宝藏 题解
题目描述 分析 先放一张图便于理解 这一道题如果暴力建图会被卡成\(n^{2}\) 实际上,在我们暴力建图的时候,有很多边都是重复的 假如一行当中有许多横天门的话,我们就不必要把这一行当中的所有点和每 ...
随机推荐
- @atcoder - AGC036F@ Square Constraints
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个整数 N,统计有多少个 0~2N-1 的排列 \(P_0 ...
- mysql 开篇
Mysql 教程 mysql是最流行的关系型数据库管理系统,在wab应用方面mysql是最好的RDBMS(Relational Database Manangement System: 关系数据库管理 ...
- 《C语言深度解剖》学习笔记之内存管理
第5章 内存管理 1.野指针 定义指针变量的同时最好初始化为NULL,用完指针后也将变量的值设置为NULL.也就是说除了使用时,别的时间都把它设置为NULL 2.堆,栈和静态区 堆:由malloc系列 ...
- redhat6.5安装oracle11_2R
参照前人一步一步操作: http://leihenzhimu.blog.51cto.com/3217508/1685164 遇到如下错误: This is a prerequisite conditi ...
- 2018-2-13-win10-uwp-如何让WebView标识win10手机
title author date CreateTime categories win10 uwp 如何让WebView标识win10手机 lindexi 2018-2-13 17:23:3 +080 ...
- ORACLE| ORACLE基础语法汇总
创 ORACLE| ORACLE基础语法汇总 2018-07-18 16:47:34 YvesHe 阅读数 9141更多 分类专栏: [数据库] 版权声明:本文为博主原创文章,遵循CC 4.0 B ...
- Ubuntu 开机自动挂载磁盘
Ubuntu 磁盘挂载 1.使用命令查看分区 sudo fdisk -l 1 可以根据上图提供的磁盘信息确定想挂载的磁盘,以及确定挂载的位置. 我此次的目的是将/dev/sda2 磁盘挂载到/mnt/ ...
- JS 复制文本兼容移动端 iOS & android
有几个需要注意的地方. 首先文本只有选中才可以复制,所以简单的做法就是创建一个隐藏的 input,然后绑定需要复制的文本. 另外如果将 input 设置为 `type="hidden&quo ...
- gSOAP calc服务端与客户端示例
1. Web服务定义描述头文件 typedef double xsd__double; int ns__add(xsd__double a, xsd__double b, xsd__double &a ...
- HDU 5974"A Simple Math Problem"(GCD(a,b) = GCD(a+b,ab) = 1)
传送门 •题意 已知 $a,b$,求满足 $x+y=a\ ,\ LCM(x,y)=b$ 条件的 $x,y$: 其中,$a,b$ 为正整数,$x,y$ 为整数: •题解 关键式子:设 $a,b$ 为正整 ...