【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP
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
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
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的更多相关文章
- BZOJ 1924 所驼门王的宝藏(强连通分量缩点+DAG最长链)
思路不是很难,因为宝藏只会在给出的n个点内有,于是只需要在这n个点里面连边,一个点如果能到达另一个点则连一条有向边, 这样用强连通分量缩点后答案就是DAG的最长链. 问题在于暴力建图是O(n^2)的, ...
- bzoj 1924 所驼门王的宝藏
题目大意: 有一个r*c的矩阵,上面有n个点有宝藏 每个有宝藏的点上都有传送门 传送门有三种:第一种可以传到该行任意一个有宝藏的点,第二种可以传到该列任意一个有宝藏的点,第三种可以传到周围的八连块上有 ...
- 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)
「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...
- 「模拟8.18」字符串(卡特兰数)·乌鸦喝水(树状数组,二分)·所驼门王的宝藏(tarjan,拓扑)
最近好颓啊,所以啥都做不出来 简单说一下这次考试,分机房了,还分不同考卷,果然我还是留在二机房的蒟蒻, 大概也只有这样的简单题,才能勉强水个rank 3吧........ 其实不必管在哪个机房,努力便 ...
- [BZOJ 1924][Sdoi2010]所驼门王的宝藏
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1285 Solved: 574[Submit][Sta ...
- 8.18 NOIP模拟测试25(B) 字符串+乌鸦喝水+所驼门王的宝藏
T1 字符串 卡特兰数 设1为向(1,1)走,0为向(1,-1)走,限制就是不能超过$y=0$这条线,题意转化为从(0,0)出发,走到(n+m,n-m)且不越过$y=0$,然后就裸的卡特兰数,$ans ...
- 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
[题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...
- noip模拟5[string·matrix·big·所驼门王的宝藏]
怎么说呢这一场考得还算可以呢 拿了120pts,主要是最后一个题灵光开窍,想起来是tarjan,然后勉勉强强拿了40pts,本来是可以拿满分的,害 没事考完了就要反思 这场考试我心态超好,从第一个题开 ...
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...
随机推荐
- MySQL迁移[转]
http://dbarobin.com/2015/09/15/migration-of-mysql-on-different-scenes/ MySQL 迁移方案概览 MySQL 迁移无非是围绕着数据 ...
- Android项目,从web上取下汉字,中文部分乱码
Android项目,从web上取下汉字,中文部分乱码. 常见问题,搜索一下,网上有很多办法解决.如果还没有试过这个办法,可以尝试一下. BufferedReader in = new Buffered ...
- 如果动态设置json对象的key
项目中要求动态设置json的key属性,如果按照一般的json设置方法是不行的.假如你把一个key设置为一个变量的话,那么最后js解析出来的就是key为这个变量名而不是这个变量的值. 解决:通过使用 ...
- css3属性书写顺序
今天写了个小demo想要利用transition 和transform以及transition-delay来实现鼠标移上去的延时动画,结果发现不能实现transition的变化效果.调试后发现只有把 ...
- NOI2018准备Day2
昨天雄心壮志了一番,今天就有点儿松懈了,是生于忧患,死于安乐吗 刷了15道大水题,5道字符串,5道多维数组,5道顺序查找,9个小时,平均40分钟一道水题,目标10分钟一道......昨天才刷了20道. ...
- node基础06:回调函数
1.Node异步编程 Node.js 异步编程的直接体现就是回调. 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了. 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,No ...
- 微信小程序 开发 微信开发者工具 快捷键
微信小程序已经跑起来了.快捷键设置找了好久没找到,完全凭感觉.图贴出来.大家看看. 我现在用的是0.10.101100的版本,后续版本更新快捷键也应该不会有什么变化. 现在貌似不能修改.如果有同学找到 ...
- scala 学习笔记(01) 函数定义、分支、循环、异常处理、递归
package yjmyzz import scala.io.StdIn object ScalaApp { def main(args: Array[String]) { println(" ...
- 乐易贵宾VIP教程:百度贴吧 - QQ部落 - QQ空间 Post实战系列视频课程
教程挺不错,3套案例的实战,有需要的可以看一下百度贴吧课程目录:1.百度登录抓包分析2.百度登录[代码实现]3.百度验证码登录[代码实现]4.贴吧关注[抓包分析]5.贴吧关注(代码编写)6.贴吧签到[ ...
- 用python代码做configure文件
在lua中,我一直用lua作为config文件,或者承载数据的文件 - 好处是lua本身就很好阅读,然后无需额外写解析的代码,还支持在configure文件中读环境变量,条件判断等,方便又强大! (在 ...