Luogu4700 CEOI2011 Traffic Tarjan、搜索
题意:给出平面上$N$个点,它们一定在左下角为$(0,0)$,右上角为$(A,B)$的一个矩形内的整点上(包括边界),而且会给出$M$条呈直线的边,其中有有向边也有无向边,保证任意两条边不会在非顶点处相交。现在我们定义横坐标为$0$的点为在西边的点,横坐标为$A$的点为在东边的点,现在请求出每一个在西边的点都能通过给出的边到达多少在东边的点。$N \leq 3 \times 10^5 , M \leq 9 \times 10^5 , 1 \leq A , B , \text{点的坐标} \leq 10^9$
其实还是挺考验思维的
首先一看到这道题:诶这不是裸的$tarjan$套记搜吗,然后打完发现会算重很多东西,样例都过不了qwq。
其实题目中有一句话十分隐蔽:保证任意两条边不会在非顶点处相交,这会给我们什么信息呢?
直接讲结论:除了无法到达的点,每一个西边的能够到达的东边的点都会对应纵坐标的一段区间,也就是说一定是从上往下一段连续的点,而如果其中有无法到达的点,那么一定是所有的西边的点都无法到达它。这个结论与引水入城的思想十分类似。所以我们可以先缩点,然后在剩下的$DAG$上进行记忆化搜索,把每一个西边的点能够到达的东边的点对应的区间记录下来(显然这个是很好记录的,只要记录两个端点即可),然后再去检索是否有无法到达且在这一段区间内的东边的点,将其扣除即可。
关于下面的代码,思想与上面一致,只是为了易于统计答案,将所有的边都取反,然后统计每一个东边的点能够影响的西边的点的区间,然后用前缀和获得每一个西边节点的答案,最后去看每一个西边的点对应的强连通分量是否被到达过(没有就表示没有东边的点可以到达它,自然答案就是$0$)
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
struct Edge{
int end , upEd;
}Ed[MAXN * ] , newEd[MAXN * ];
struct node{
int y , ind;
}now[MAXN];
][MAXN] , ind[MAXN] , num[MAXN] , s[MAXN] , dfn[MAXN] , low[MAXN];
int N , M , A , B , cntEd , cntNode , ts , headS , cntNewEd , cntSCC;
bool vis[MAXN] , ins[MAXN] , ine[MAXN];
queue < int > q;
inline void addEd(Edge* Ed , int* head , int& cntEd , int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
void tarjan(int x){
dfn[x] = low[x] = ++ts;
vis[x] = ins[x] = ;
s[++headS] = x;
for(int i = head[x] ; i ; i = Ed[i].upEd){
if(!vis[Ed[i].end])
tarjan(Ed[i].end);
else
if(!ins[Ed[i].end])
continue;
low[x] = min(low[Ed[i].end] , low[x]);
}
if(dfn[x] == low[x]){
cntSCC++;
do{
int t = s[headS];
in[t] = cntSCC;
ins[t] = ;
if(ind[t]){
len[][cntSCC] = min(len[][cntSCC] , ind[t]);
len[][cntSCC] = max(len[][cntSCC] , ind[t]);
}
}while(s[headS--] != x);
}
}
void create(){
; i <= N ; i++)
for(int j = head[i] ; j ; j = Ed[j].upEd)
if(in[Ed[j].end] != in[i])
addEd(newEd , newHead , cntNewEd , in[i] , in[Ed[j].end]);
}
void dfs(int x){
if(vis[x])
return;
vis[x] = ;
for(int i = newHead[x] ; i ; i = newEd[i].upEd){
dfs(newEd[i].end);
len[][x] = min(len[][x] , len[][newEd[i].end]);
len[][x] = max(len[][x] , len[][newEd[i].end]);
}
}
bool operator <(node a , node b){
return a.y > b.y;
}
int main(){
#ifdef LG
freopen("4700.in" , "r" , stdin);
freopen("4700.out" , "w" , stdout);
#endif
memset(len[] , ]));
N = read();
M = read();
A = read();
B = read();
; i <= N ; i++){
int x = read() , y = read();
if(x == A)
ine[i] = ;
else
if(!x){
now[++cntNode].y = y;
now[cntNode].ind = i;
}
}
; i <= M ; i++){
int a = read() , b = read() , c = read();
addEd(Ed , head , cntEd , b , a);
)
addEd(Ed , head , cntEd , a , b);
}
sort(now + , now + cntNode + );
; i <= cntNode ; i++)
ind[now[i].ind] = i;
; i <= N ; i++)
if(!vis[i])
tarjan(i);
memset(vis , , sizeof(vis));
create();
; i <= N ; i++)
if(ine[i]){
dfs(in[i]);
][][in[i]]){
num[len[][in[i]]]++;
num[len[][]--;
}
}
; i <= cntNode ; i++)
num[i] += num[i - ];
; i <= cntNode ; i++)
cout << (!vis[ : num[i]) << endl;
;
}
Luogu4700 CEOI2011 Traffic Tarjan、搜索的更多相关文章
- [Ceoi2011]Traffic
#2387. [Ceoi2011]Traffic Online Judge:Bzoj-2387,Luogu-4700 Label:Yy,Tarjan缩点,dfs 题目描述 格丁尼亚的中心位于Kacza ...
- bzoj 2387: [Ceoi2011]Traffic
bzoj 2387: [Ceoi2011]Traffic 题目描述 The center of Gdynia is located on an island in the middle of the ...
- 152 - - G Traffic Light 搜索(The 18th Zhejiang University Programming Contest Sponsored by TuSimple )
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5738 题意 给你一个map 每个格子里有一个红绿灯,用0,1表示 ...
- tarjan - tarjan的几种用法
前言 tarjan是一种神奇的算法, 它可以在线性时间内求强联通分量/缩点/LCA/割点/割边/... 但由于博主咸鱼,暂时掌握不了这么多, 先讲讲其中最简单的一些. 概述 tarjan是以DFS为基 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- UVA-315 无向图求割点个数
题意抽象: 给定一个无向图,输出割点个数. 割点定义:删除该点后,原图变为多个连通块. 考虑一下怎么利用tarjan判定割点: 对于点u和他相连的当时还未搜到的点v,dfs后如果DFN[u]<= ...
- Codeforces Round #377 (Div. 2) F - Tourist Reform
前言:关于如何求双连通分量,我们可以在tarjan搜索时标记下所有桥的位置(双连通分量(可以认为是没有桥的无向图图)即可通过删去所有桥得到),那么怎么找桥呢,对于每一条搜索到的边u->x,如果l ...
- ASO--简单了解
ASO是“应用商店优化”的简称.ASO(App Search Optimization)就是提升你APP在各类APP应用商店/市场排行榜和搜索结果排名的过程. 类似普通网站针对搜索引擎的优化,即SEO ...
- luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)
先跑一边dijkstra算出从1到i的最短距离dis[i] 然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数 答案就是$\sum\limits_{i=0}^{k} ...
随机推荐
- 【读书笔记】iOS-属性
assign:简单的赋值. retain:赋值之后,会调用新的retain方法和旧值的release方法. copy:表示先将值拷贝一份,然后,将这个拷贝赋值给实例变量,这个修饰词只适用于实现了NSC ...
- App里面如何正确显示用户头像
1.说明,一般用户头像在上传的时候都会处理为正方形,如果没有处理该怎么正确显示用户头像呢?解决方案:用css强制 在线地址移动端:戳这里 <div class="main-meimg& ...
- 《ASP.NET MVC企业实战》(三)MVC开发前奏
在上一篇“<ASP.NET MVC企业级实战>(二)MVC开发前奏”中跟随作者大概了解了一些C#3.0和3.5中的新特性.本篇继续以这样的方式来学习C#中的一些特性. 一.C#3. ...
- Android--实现ViewPager边界回弹效果(转)
该View转自 http://blog.csdn.net/Kalwang/article/details/4708721 ,感谢这位大神. public class BounceBackView ...
- Expo大作战(三十八)--expo sdk api之 FileSystem(文件操作系统)
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- JMeter—定时器(八)
参考<全栈性能测试修炼宝典JMeter实战>第六章 JMeter 元件详解中第三节定时器 JMeter中的定时器一般用来设置延迟与同步.定时器的执行优先级高于取样器,在同一作用域下有多个定 ...
- C# RSA 加密
class Sign_verifySign { #region prepare string to sign. //example format: a=123&b=xxx&c (wit ...
- 重写EasyUI的$.fn.datagrid.defaults.editors
$.extend($.fn.datagrid.defaults.editors, { numberbox: { init: function (container, options) { var in ...
- mysql 临时数据突然变大
晚上收到紧报警,一台数据库服务器磁盘空间使用快速从50%使用率到80%.我们生产的数据库都磁盘是>2T 登录机器发现*.myd文件异常大 登入数据库查询进程 mysql>showproce ...
- docker修改容器gogs时区时间
问题描述: 公司内部搭建了一个gogs-git,是用docker部署的,但是发现提交的代码什么的时间跟服务器时间不一致 提交上去的世界是UTC时间不是中国的时间CST,相当于慢了8个小时 1.dock ...