传送门

题意:给出平面上$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、搜索的更多相关文章

  1. [Ceoi2011]Traffic

    #2387. [Ceoi2011]Traffic Online Judge:Bzoj-2387,Luogu-4700 Label:Yy,Tarjan缩点,dfs 题目描述 格丁尼亚的中心位于Kacza ...

  2. bzoj 2387: [Ceoi2011]Traffic

    bzoj 2387: [Ceoi2011]Traffic 题目描述 The center of Gdynia is located on an island in the middle of the ...

  3. 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表示 ...

  4. tarjan - tarjan的几种用法

    前言 tarjan是一种神奇的算法, 它可以在线性时间内求强联通分量/缩点/LCA/割点/割边/... 但由于博主咸鱼,暂时掌握不了这么多, 先讲讲其中最简单的一些. 概述 tarjan是以DFS为基 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. UVA-315 无向图求割点个数

    题意抽象: 给定一个无向图,输出割点个数. 割点定义:删除该点后,原图变为多个连通块. 考虑一下怎么利用tarjan判定割点: 对于点u和他相连的当时还未搜到的点v,dfs后如果DFN[u]<= ...

  7. Codeforces Round #377 (Div. 2) F - Tourist Reform

    前言:关于如何求双连通分量,我们可以在tarjan搜索时标记下所有桥的位置(双连通分量(可以认为是没有桥的无向图图)即可通过删去所有桥得到),那么怎么找桥呢,对于每一条搜索到的边u->x,如果l ...

  8. ASO--简单了解

    ASO是“应用商店优化”的简称.ASO(App Search Optimization)就是提升你APP在各类APP应用商店/市场排行榜和搜索结果排名的过程. 类似普通网站针对搜索引擎的优化,即SEO ...

  9. luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)

    先跑一边dijkstra算出从1到i的最短距离dis[i] 然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数 答案就是$\sum\limits_{i=0}^{k} ...

随机推荐

  1. Hbase简单配置与使用

    一. HBase的 二.基于Hadoop的HBase架构 HBase内置有zookeeper,但一般我们会有其他的Zookeeper集群来监管master和regionserver,Zookeeper ...

  2. 测试中Android与IOS分别关注的点

    主要从本身系统的不同点.系统造成的不同点.和注意的测试点做总结 1.自身不同点 研发商:Adroid是google公司做的手机系统,IOS是苹果公司做的手机系统 开源程度:Android是开源的,IO ...

  3. 洗礼灵魂,修炼python(47)--巩固篇—定义类的方法之@classmethod,@staticmethod

    定义类的方法,相信你会说,不就是在class语句下使用def () 就是定义类的方法了嘛,是的,这是定义的方法的一种,而且是最普通的方式 首先,我们已经知道有两种方式: 1.普通方法: 1)与类无关的 ...

  4. Excel实用录入技巧

    一.文本录入技巧 输入开头为0的序号 当直接输入单元格中的数字第一个为0时系统会默认去掉 只需要经单元格格式改为文本或者在单元格输入前使用英文状态下的单引号(‘) 例如:'0001 >>& ...

  5. 机器学习中学习曲线的 bias vs variance 以及 数据量m

    关于偏差.方差以及学习曲线为代表的诊断法: 在评估假设函数时,我们习惯将整个样本按照6:2:2的比例分割:60%训练集training set.20%交叉验证集cross validation set ...

  6. 浅copy与深copy举例

     例1: #!/usr/bin/env python import copy d1 = {'x':1,'y':2,'z':[3,4.5]} d2 = d1 d3 = d1.copy() d4 = co ...

  7. oracle数据库用户基本操作

    每个数据库都有一系列的用户,为了访问数据库,用户必须使用用户名等信息先连接上数据库实例,oracle数据库提供了多种方式来管理用户安全.创建用户的时候,可以通过授权等操作来限制用户能访问的资源以及一些 ...

  8. [BUG]Appium1.9.1 这个问题竟然花了我5分钟进行定位

    1.先上问题,知道是什么问题先 EE ====================================================================== ERROR: tes ...

  9. <table>标签总结(colspan跨列 ,rowspan跨行)

    table标签有些内置属性要设置: <table cellpadding="0" cellspacing="0" border="0" ...

  10. 关于一台机器部署多个tomcat的小记

    一台机器部署多个tomcat在很多时候都是有可能的,比如说多个tomcat配合nginx负载更可能好的利用CPU,或者更新程序时做主备切换等. 1.直接下载或者复制一个已有的tomcat,第一个tom ...