题解 [SDOI2010]所驼门王的宝藏
保分题再度爆零,自闭ing×2
tarjan没写vis数组,点权算的也有点问题
这题情况3的连边有点麻烦,考场上想了暴力想了二分就是没想到可以直接拿map水过去
不过map果然贼慢,所以这也是一个哈希表的板子题
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define ld long double
#define usd unsigned
#define ull unsigned long long
//#define int long long
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
struct hush_map{
static const int SIZE=100010;
struct node{pair<int, int> p; int dat, next;}e[SIZE<<1];
int head[SIZE], size;
hush_map():size(0){memset(e, 0, sizeof(e));}
inline int operator [] (pair<int, int> p) {
ll t = 1ll*p.first*p.second%SIZE;
for (int i=head[t]; i; i=e[i].next) {
if (e[i].p==p) return e[i].dat;
}
return 0;
}
inline void add(pair<int, int> p, int dat) {
ll t = 1ll*p.first*p.second%SIZE;
node *k=&e[++size];
k->p=p; k->dat=dat; k->next=head[t];
head[t] = size;
}
};
struct edge{int from, to, next;}e[N*60]; // 乱开的大小
int r, c, n;
int head[N], size=1, cnt[N], val[N];
int dfn[N], low[N], siz, s[N], top, fa[N], h[N], tot[N];
bool vis[N];
//unsigned short mp[5005][5005];
//map<pair<int,int>, int> mp;
hush_map mp;
const int dir[][2] = {{-1,1},{-1,0},{-1,-1},{0,1},{0,-1},{1,1},{1,0},{1,-1}};
struct point{int x, y, k, rank; inline void build(int i){x=read(); y=read(); k=read(); mp.add(pair<int, int>(x, y), i); rank=i;}}p[N];
inline bool cmpx(point a, point b) {return a.x==b.x?a.y<b.y:a.x<b.x;}
inline bool cmpy(point a, point b) {return a.y==b.y?a.x<b.x:a.y<b.y;}
inline void add(int s, int t) {edge *k=&e[++size]; k->from=s; k->to=t; k->next=head[s]; head[s]=size;}
inline void add2(int s, int t) {edge *k=&e[++size]; k->from=s; k->to=t; k->next=h[s]; h[s]=size;}
inline int find(int u) {return fa[u]==u?u:fa[u]=find(fa[u]);}
void tarjan(int u) {
//cout<<"tarjan "<<u<<endl;
dfn[u]=low[u]=++siz;
s[++top] = u;
vis[u] = 1;
for (int i=head[u],v; i; i=e[i].next) {
v = e[i].to;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (vis[v]) low[u] = min(low[u], low[v]);
}
if (dfn[u] == low[u]) {
//cout<<"node"<<endl;
int t=find(u), f;
while (s[top]!=u) {
f = find(s[top]);
vis[s[top]]=0;
cnt[t] += cnt[f];
fa[s[top--]] = t;
}
--top;
vis[u] = 0;
}
}
signed main()
{
#ifdef DEBUG
freopen("1.in", "r", stdin);
#endif
//cout<<double(sizeof(head)*9+sizeof(mp)+sizeof(e)+sizeof(p))/1024/1024<<endl;
n=read(); r=read(); c=read();
for (int i=1; i<=n; ++i) p[i].build(i), val[i]=1;
for (int i=1; i<=n; ++i) fa[i]=i, cnt[i]=1;
sort(p+1, p+n+1, cmpx);
for (int i=1,keypoint; i<=n; ++i) {
if (i==0 || p[i].x!=p[i-1].x) keypoint=0;
if (p[i].k==1) {
if (keypoint) add(p[i].rank, keypoint);
else {
for (int j=i-1; j&&p[j].x==p[i].x; --j) add(p[i].rank, p[j].rank);
for (int j=i+1; j<=n&&p[j].x==p[i].x; ++j) add(p[i].rank, p[j].rank);
keypoint = p[i].rank;
}
}
}
sort(p+1, p+n+1, cmpy);
for (int i=1,keypoint; i<=n; ++i) {
if (i==0 || p[i].y!=p[i-1].y) keypoint=0;
if (p[i].k==2) {
if (keypoint) add(p[i].rank, keypoint);
else {
for (int j=i-1; j&&p[j].y==p[i].y; --j) add(p[i].rank, p[j].rank);
for (int j=i+1; j<=n&&p[j].y==p[i].y; ++j) add(p[i].rank, p[j].rank);
keypoint = p[i].rank;
}
}
}
#if 0
for (int i=1; i<=n; ++i)
if (p[i].k==3) {
int x=p[i].x, y=p[i].y, r=p[i].rank, t;
for (int j=0; j<8; ++j) {
t = mp[x+dir[j][0]][y+dir[j][1]];
if (t) add(r, t);
}
}
#else
for (int i=1; i<=n; ++i)
if (p[i].k==3) {
int x=p[i].x, y=p[i].y, r=p[i].rank, t;
for (int j=0; j<8; ++j) {
t = mp[pair<int,int>(x+dir[j][0], y+dir[j][1])];
if (t) add(r, t);
}
}
#endif
for (int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i);
memset(vis, 0, sizeof(vis));
//for (int i=1; i<=n; ++i) cout<<find(i)<<endl;
//cout<<"dfn "; for (int i=1; i<=n; ++i) cout<<dfn[i]<<' '; cout<<endl;
//cout<<"low "; for (int i=1; i<=n; ++i) cout<<low[i]<<' '; cout<<endl;
//cout<<"cnt "; for (int i=1; i<=n; ++i) cout<<cnt[i]<<' '; cout<<endl;
int lim=size;
for (int i=1,f1,f2; i<=lim; ++i) {
f1=find(e[i].from); f2=find(e[i].to);
vis[f1]=1; vis[f2]=1;
if (f1 != f2) {
add2(f1, f2); ++tot[f2];
}
}
//cout<<"vis "; for (int i=1; i<=n; ++i) cout<<vis[i]<<' '; cout<<endl;
queue<int> q;
for (int i=1; i<=n; ++i) if (!tot[i] && vis[i]) q.push(i), val[i]=cnt[i]; //, cout<<"push "<<i<<endl;
while (!q.empty()) {
int u=q.front(); q.pop();
for (int i=h[u],v; i; i=e[i].next) {
v = e[i].to;
val[v] = max(val[v], val[u]+cnt[v]); //, cout<<" -> "<<u<<' '<<v<<" "<<val[v]<<' '<<(val[u]+cnt[v])<<endl;
//assert(find(v)!=find(u));
if (--tot[v]==0) q.push(v);
}
}
//cout<<"cnt "; for (int i=1; i<=n; ++i) cout<<cnt[i]<<' '; cout<<endl;
int ans=1;
for (int i=1; i<=n; ++i) if (vis[i]) ans=max(ans, val[i]);
printf("%d\n", ans);
return 0;
}
题解 [SDOI2010]所驼门王的宝藏的更多相关文章
- 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
[题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...
- [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}\) 实际上,在我们暴力建图的时候,有很多边都是重复的 假如一行当中有许多横天门的话,我们就不必要把这一行当中的所有点和每 ...
- 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列的藏宝宫室 ...
随机推荐
- 「AGC023D」 Go Home
「AGC023D」 Go Home 传送门 神题. 首先我们可以倒着考虑. 当车到达最后一栋楼的时候,车上一定只有到这栋楼的员工. 当车到达倒数第二栋楼的时候,车上一定只有到达剩下两栋楼的员工. 设这 ...
- Activiti7 回退与会签
1. 回退(驳回) 回退的思路就是动态更改节点的流向.先遇水搭桥,最后再过河拆桥. 具体操作如下: 取得当前节点的信息 取得当前节点的上一个节点的信息 保存当前节点的流向 新建流向,由当前节点指向上 ...
- .h .cpp区别
首先,我们可以将所有东西都放在一个.cpp文件内. 然后编译器就将这个.cpp编译成.obj,obj是什么东西? 就是编译单元了.一个程序,可以由一个编译单元组成, 也可以有多个编译单元组成. 如果你 ...
- Spark RDD编程-大数据课设
目录 一.实验目的 二.实验平台 三.实验内容.要求 1.pyspark交互式编程 2.编写独立应用程序实现数据去重 3.编写独立应用程序实现求平均值问题 四.实验过程 (一)pyspark交互式编程 ...
- Spring Boot邮箱链接注册验证
Spring Boot邮箱链接注册验证 简单介绍 注册流程 [1]前端提交注册信息 [2]后端接受数据 [3]后端生成一个UUID做为token,将token作为redis的key值,用户数据作为re ...
- Spring中定时任务@Scheduled的一点小小研究
最近做一个公众号项目,微信公众号会要求服务端找微信请求一个access_token,获取的过程: access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_tok ...
- 【剑指offer】77.调整数组顺序使奇数位于偶数前面
77.调整数组顺序使奇数位于偶数前面 知识点:数组:快速排序:冒泡排序: 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部 ...
- AI开发者十问:10分钟了解AI开发的基本过程
摘要:从AI开发模型.框架.工具,到提升开发效率的学习办法,为AI开发者逐一解答. 本文分享自华为云社区<10分钟了解AI开发的基本过程>,作者:简单坚持. 1.AI开发究竟在开发什么? ...
- HCNA Routing&Switching之OSPF度量值和基础配置命令总结
前文我们了解了OSPF的网络类型,OSPF中的DR和BDR的选举规则.作用等相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15054938.html: ...
- Python开发篇——如何在Flask下编写JWT登录
首先,HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息)--每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求 ...