「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路)

-----------------------------------------------------------------------------------------------------------------------------------------

在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族。被族人恭称为“先知”的 Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”。所驼门王毕生致力于维护家族的安定与和谐,他曾亲自率军粉碎河蟹帝国主义的野蛮侵略,为族人立下赫赫战功。所驼门王一生财宝无数,但因其生性节俭低调, 他将财宝埋藏在自己设计的地下宫殿里,这也是今天 Henry Curtis 故事的起点。Henry 是一个爱财如命的贪婪家伙,而又非常聪明,他费尽心机谋划了这次盗窃行动,破解重重机关后来到这座地下宫殿前。

-----------------------------------------------------------------------------------------------------------------------------------------

整座宫殿呈矩阵状,由 R×C 间矩形宫室组成,其中有 N 间宫室里埋藏着宝藏,称作藏宝宫室。宫殿里外、相邻宫室间都由坚硬的实体墙阻隔,由一间宫室到达另一间只能通过所驼门王独创的移动方式——传送门。所驼门王为这 N 间藏宝宫室每间都架设了一扇传送门,没有宝藏的宫室不设传送门,所有的宫室传送门分为三种:

1、“横天门”:由该门可以传送到同行的任一宫室;

2、“纵寰门”:由该门可以传送到同列的任一宫室;

3、“自 由 门”:由该门可以传送到以该门所在宫室为中心周围8格中任一宫室(如果目标宫室存在的话)。

深谋远虑的 Henry 当然事先就搞到了所驼门王当年的宫殿招标册,书册上详细记录了每扇传送门所属宫室及类型。而且,虽然宫殿内外相隔,但他自行准备了一种便携式传送门,可将自己传送到殿内任意一间宫室开始寻宝,并在任意一间宫室结束后传送出宫。整座宫殿只许进出一次,且便携门无法进行宫室之间的传送。不过好在宫室内传送门的使用没有次数限制,每间宫室也可以多次出入。

现在 Henry 已经打开了便携门,即将选择一间宫室进入。为得到尽多宝藏, 他希望安排一条路线,使走过的不同藏宝宫室尽可能多。请你告诉 Henry 这条路 线最多行经不同藏宝宫室的数目。

-----------------------------------------------------------------------------------------------------------------------------------------
「输入格式」

第一行给出三个正整数 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,所有的传送门位置互不相同。

「输出格式」

只有一个正整数,表示你确定的路线所经过不同藏宝 宫室的最大数目。

-----------------------------------------------------------------------------------------------------------------------------------------
「样例输入输出」

输入

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

输出

9

-----------------------------------------------------------------------------------------------------------------------------------------
「数据规模和约定」

测试点编号 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

-----------------------------------------------------------------------------------------------------------------------------------------

题解

考虑到 N <= 100,000 矩阵上的点应该很稀疏
于是考虑直接建图做

但是连边的时候将一行中所有“横天门”连在一起 复杂度是 O(N^2)
将一列中所有“纵寰门”连在一起 复杂度也是 O(N^2)

于是考虑将一行中所有“横天门”缩成一个点(将每个“横天门”向该行第一个“横天门”连双向边)
将一列中所有“纵寰门”也缩成一个点(同理)

复杂度就可以降为线性的

再在建好的图上跑 tarjan 把图转为 DAG 再跑 有向无环图的最长路 (dp)

 #include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+;
const int MAXE=1e6+;
int dx[]={,,,,,-,-,-},dy[]={,-,,,-,,,-};
int edge,nex[MAXE],head[MAXN],tail[MAXE];
int redge,rnex[MAXE],rhead[MAXN],rtail[MAXE];
int n,m,r,c;
struct rec{ int x,y,t; } loc[MAXN];
int f[MAXN];
map<int,int> mp[MAXE];
vector<int> a[MAXE],b[MAXE];
int q[MAXN],top=,scc=;
int use[MAXN],cmp[MAXN],low[MAXN],dfn[MAXN],num[MAXN],cnt,ans;
void add(int u,int v){
if (u==v) return;
edge++,nex[edge]=head[u],head[u]=edge,tail[edge]=v;
}
void radd(int u,int v){
redge++,rnex[redge]=rhead[u],rhead[u]=redge,rtail[redge]=v;
}
void clean(){ memset(use,,sizeof(use)); }
void build(){
for (int i=;i<=r;i++){
int x=;
for (int j=;j<a[i].size();j++) if (loc[a[i][j]].t==){ x=a[i][j]; break; }
for (int j=;j<a[i].size();j++){
add(x,a[i][j]);
if (loc[a[i][j]].t==) add(a[i][j],x);
}
}
for (int i=;i<=c;i++){
int x=;
for (int j=;j<b[i].size();j++) if (loc[b[i][j]].t==){ x=b[i][j]; break; }
for (int j=;j<b[i].size();j++){
add(x,b[i][j]);
if (loc[b[i][j]].t==) add(b[i][j],x);
}
}
for (int i=;i<=n;i++){
if (loc[i].t!=) continue;
int x=loc[i].x,y=loc[i].y;
for (int j=;j<;j++){
if (mp[x+dx[j]][y+dy[j]]>) add(i,mp[x+dx[j]][y+dy[j]]);
}
}
}
void tarjan(int u){
low[u]=dfn[u]=++cnt;
q[++top]=u,use[u]=;
for (int e=head[u];e;e=nex[e]){
int v=tail[e];
if (!dfn[v]){
tarjan(v); low[u]=min(low[u],low[v]);
}
else if (use[v]) low[u]=min(low[u],dfn[v]);
}
if (low[u]==dfn[u]){
int x=; scc++;
while (x!=u){
x=q[top--];use[x]=;
cmp[x]=scc;num[scc]++;
}
}
}
void rebuild(){
for (int u=;u<=n;u++){
for (int e=head[u];e;e=nex[e]){
int v=tail[e];
if (cmp[u]!=cmp[v]) radd(cmp[u],cmp[v]);
}
}
}
void dp(int u){
use[u]=;
for (int e=rhead[u];e;e=rnex[e]){
int v=rtail[e];
if (!use[v]) dp(v);
f[u]=max(f[u],f[v]);
}
f[u]+=num[u];
ans=max(ans,f[u]);
}
int main(){
scanf("%d%d%d",&n,&r,&c);
for (int i=;i<=n;i++){
scanf("%d%d%d",&loc[i].x,&loc[i].y,&loc[i].t);
a[loc[i].x].push_back(i);
b[loc[i].y].push_back(i);
mp[loc[i].x][loc[i].y]=i;
}
build();
clean();
for (int i=;i<=n;i++){
if (!dfn[i]) tarjan(i);
}
rebuild();
clean();
for (int i=;i<=scc;i++){
if (!use[i]) dp(i);
}
printf("%d\n",ans);
return ;
}

「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)的更多相关文章

  1. 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  2. 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Stat ...

  3. 「模拟8.18」字符串(卡特兰数)·乌鸦喝水(树状数组,二分)·所驼门王的宝藏(tarjan,拓扑)

    最近好颓啊,所以啥都做不出来 简单说一下这次考试,分机房了,还分不同考卷,果然我还是留在二机房的蒟蒻, 大概也只有这样的简单题,才能勉强水个rank 3吧........ 其实不必管在哪个机房,努力便 ...

  4. [BZOJ 1924][Sdoi2010]所驼门王的宝藏

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1285  Solved: 574[Submit][Sta ...

  5. 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)

    [题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...

  6. 8.18 NOIP模拟测试25(B) 字符串+乌鸦喝水+所驼门王的宝藏

    T1 字符串 卡特兰数 设1为向(1,1)走,0为向(1,-1)走,限制就是不能超过$y=0$这条线,题意转化为从(0,0)出发,走到(n+m,n-m)且不越过$y=0$,然后就裸的卡特兰数,$ans ...

  7. noip模拟5[string·matrix·big·所驼门王的宝藏]

    怎么说呢这一场考得还算可以呢 拿了120pts,主要是最后一个题灵光开窍,想起来是tarjan,然后勉勉强强拿了40pts,本来是可以拿满分的,害 没事考完了就要反思 这场考试我心态超好,从第一个题开 ...

  8. [SDOI2010]所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  9. [LuoguP2403][SDOI2010]所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

随机推荐

  1. Session.Abandon-Session.Clear-Session.RemoveAll

    System.Web.UI.Page.Session属性和System.Web.HttpContext.Session属性 都是System.Web.SessionState.HttpSessionS ...

  2. What is the AppData folder?

    Applies to Windows 8.1, Windows RT 8.1 The AppData folder contains app settings, files, and data spe ...

  3. AutoLayout自动布局之VFL语言代码实现(一个神奇的语言)

    一.什么是VFL语言?为什么要VFL语言? VFL全称是Visual Format Language,翻译过来是“可视化格式语言” VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言 ...

  4. 关于Html5中的单选与多选

    1.下拉列表样式: <select> <option value ="volvo">Volvo</option> <option valu ...

  5. Extjs Hello extjs

    <html > <head runat="server"> <title></title> <link rel="s ...

  6. C# web通信解决方案

    1.Socket 2.Socket and websocket(HTML5) 3.SignalR 一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket ...

  7. webapi put 请求405问题

    put 请求的时候  浏览器会像服务器发送两个请求 如何没做任何配置第一个options请求是会报错的 这是需要配置路由给options作响应 这时options请求就通过了,然后你们会看到你的put ...

  8. 操作系统下spinlock锁解析、模拟及损耗分析

    关于spinlock 我们在知道什么是spinlock之前,还需要知道为什么需要这个spinlock?spinlock本质就是锁,提到锁,我们就回到了多线程编程的混沌初期,为了实现多线程编程,操作系统 ...

  9. [.net 多线程] Interlocked实现CAS操作

    Interlocked:为多个线程共享的变量提供原子操作. Interlocked.Increment(ref value) 数值加一(原子性操作) Interlocked.Decrement(ref ...

  10. C#多线程编程实战1.3等待线程

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...