1924: [Sdoi2010]所驼门王的宝藏

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit:
787  Solved: 318
[Submit][Status][Discuss]

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

Source

Solution

题目并不难.

很显然Tarjan缩点,重构图,然后在DAG上做DP,或者跑最长路

麻烦的在于建图....

需要用vector存在同一行上的格点,同一列上的格点,用map记录点的八连通,然后连边

连边的方式有技巧,选一个横/竖格,对同行同列的所有点连单向边,对横/竖格连双向;八连通的直接连就好

如果暴力连边,可能会出现一组WA的情况,可能需要再进行一遍拓扑排序

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 100010
int dx[]={,,,,,-,-,-},dy[]={,-,,,-,,,-};
struct EdgeNode{int next,to;}edge[maxn*],road[maxn*];
int cnt,tot,head[maxn],last[maxn];
void addedge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
void insertedge(int u,int v) {if (u==v) return; addedge(u,v);}
void addroad(int u,int v) {tot++; road[tot].next=last[u]; last[u]=tot; road[tot].to=v;}
void insertroad(int u,int v) {addroad(u,v);}
int x[maxn],y[maxn],t[maxn],dfn[maxn],low[maxn],stack[maxn],num[maxn],belong[maxn],dp[maxn];
bool visit[maxn];
int n,r,c,ans,top,qcnt;
vector<int>h[maxn*],l[maxn*];
map<int,int>mp[maxn*];
void BuildGraph()
{
for (int i=; i<=r; i++)
{
int hn=h[i].size(),now=;
for (int j=; j<=hn-; j++) if (t[h[i][j]]==) {now=h[i][j]; break;}
for (int j=; j<=hn-; j++) {insertedge(now,h[i][j]); if (t[h[i][j]]==) insertedge(h[i][j],now);}
}
for (int i=; i<=c; i++)
{
int ln=l[i].size(),now=;
for (int j=; j<=ln-; j++) if (t[l[i][j]]==) {now=l[i][j]; break;}
for (int j=; j<=ln-; j++) {insertedge(now,l[i][j]); if (t[l[i][j]]==) insertedge(l[i][j],now);}
}
for (int i=; i<=n; i++)
if (t[i]==)
for (int xx,yy,j=; j<=; j++)
{
xx=x[i]+dx[j],yy=y[i]+dy[j];
if (mp[xx][yy]) insertedge(i,mp[xx][yy]);
}
}
void Tarjan(int x)
{
dfn[x]=low[x]=++tot; visit[x]=; stack[++top]=x;
for (int i=head[x]; i; i=edge[i].next)
{
if (!dfn[edge[i].to])
{
Tarjan(edge[i].to);
if (low[edge[i].to]<low[x]) low[x]=low[edge[i].to];
}
else
if(visit[edge[i].to] && dfn[edge[i].to]<low[x])
low[x]=dfn[edge[i].to];
}
if (dfn[x]==low[x])
{
int uu=; qcnt++;
while (x!=uu)
uu=stack[top--],num[qcnt]++,visit[uu]=,belong[uu]=qcnt;
}
}
void reBuildGraph()
{
for (int i=; i<=n; i++)
for (int j=head[i]; j; j=edge[j].next)
if (belong[i]!=belong[edge[j].to])
insertroad(belong[i],belong[edge[j].to]);
}
void DP(int now)
{
visit[now]=;
for (int i=last[now]; i; i=road[i].next)
{
if (!visit[road[i].to]) DP(road[i].to);
dp[now]=max(dp[now],dp[road[i].to]);
}
dp[now]+=num[now];
ans=max(ans,dp[now]);
}
int main()
{
n=read(); r=read(); c=read();
for (int i=; i<=n; i++)
{
x[i]=read(),y[i]=read(),t[i]=read();
mp[x[i]][y[i]]=i; h[x[i]].push_back(i); l[y[i]].push_back(i);
}
BuildGraph();
for (int i=; i<=n; i++) if (!dfn[i]) Tarjan(i);
reBuildGraph();
for (int i=; i<=qcnt; i++) if (!visit[i]) DP(i);
printf("%d\n",ans);
return ;
}

shabi题卡时卡内存是什么意思??

【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP的更多相关文章

  1. BZOJ 1924 所驼门王的宝藏(强连通分量缩点+DAG最长链)

    思路不是很难,因为宝藏只会在给出的n个点内有,于是只需要在这n个点里面连边,一个点如果能到达另一个点则连一条有向边, 这样用强连通分量缩点后答案就是DAG的最长链. 问题在于暴力建图是O(n^2)的, ...

  2. bzoj 1924 所驼门王的宝藏

    题目大意: 有一个r*c的矩阵,上面有n个点有宝藏 每个有宝藏的点上都有传送门 传送门有三种:第一种可以传到该行任意一个有宝藏的点,第二种可以传到该列任意一个有宝藏的点,第三种可以传到周围的八连块上有 ...

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

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

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

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

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

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

  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. 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)

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

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

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

  9. BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】

    Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...

随机推荐

  1. (原创)mybatis学习四,利用mybatis自动创建代码

    在使用mybatis的过程中,我们可以直接利用MyBatis生成器自动生成实体类.DAO接口和Mapping映射文件,然后copy到工程中即可 需要的jar包如下 下载路径如下:下载jar包 其中的g ...

  2. matlab:启动后无法调用工具包

    matlab有时候一打开会出现warning,然后任何工具包(包括set path)都执行不了,在网上找到解决方法,存下来备用. 1. 在matlab的command里输入: restoredefau ...

  3. Linux 进程详解

    Linux内核的七大区间 .进程管理(进程创建,进程的三种状态,进程间的调度,调度算法...) .内存管理(段式管理(Linux所有段都从0开始),页式管理--地址偏移量) .系统调用(C语言库函数的 ...

  4. 如何在mac本上安装android sdk

    众所周知的原因,google的很多网站在国内无法访问,苦逼了一堆天朝程序员,下是在mac本上折腾android 开发环境的过程: 一.先下载android sdk for mac 给二个靠谱的网址: ...

  5. java:使用匿名类直接new接口

    java中的匿名类有一个倍儿神奇的用法,见下面代码示例: package contract; public interface ISay { void sayHello(); } 上面是一个简单的接口 ...

  6. TinyFrame升级之七:重构Repository和Unit Of Work

    首先,重构的想法来源于以下文章:Correct use of Repository and Unit Of Work patterns in ASP.NET MVC,因为我发现在我的框架中,对Unit ...

  7. 乐易贵宾VIP教程:百度贴吧 - QQ部落 - QQ空间 Post实战系列视频课程

    教程挺不错,3套案例的实战,有需要的可以看一下百度贴吧课程目录:1.百度登录抓包分析2.百度登录[代码实现]3.百度验证码登录[代码实现]4.贴吧关注[抓包分析]5.贴吧关注(代码编写)6.贴吧签到[ ...

  8. <实训|第十二天>用LVM对linux分区进行动态扩容

    [root@localhost~]#序言在linux中,我们安装软件的途径一般有那些,你们知道吗?在linux中,如果你的磁盘空间不够用了,你知道如何来扩展磁盘吗?动态扩容不仅在工作中还是在其他方面都 ...

  9. 2016 5.03开始记录我的it学习。

    好多谢立成师兄给我这个网址,我发现博客园不仅仅可以随笔记载很多东西,还是一个资源丰富的网站,接下来的四年我会用心去记录这些学习的点滴.

  10. python file 文件读写

    python 文本对象 继承自C的stdio包 打开 可以用内置的open()函数创建 with open("hello.txt") as f: for line in f: pr ...