[线段树建图 bfs] BZOJ 3073 [Pa2011]Journeys

CA爷的题解:http://blog.csdn.net/CreationAugust/article/details/50739132

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
using namespace std;

inline char nc()
{
	static char buf[100000],*p1=buf,*p2=buf;
	if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
	return *p1++;
}

inline void read(int &x)
{
	char c=nc(),b=1;
	for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
	for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

const int N=500005;

struct edge{
	int l,r;
	int next;
}G[10*N];

int inum,head[4*N];

inline void add(int rt,int l,int r,int p){
	G[p].l=l; G[p].r=r; G[p].next=head[rt]; head[rt]=p;
}

int M;

inline void Build(int n){
	for (M=1;M<n+2;M<<=1);
}

inline void insert(int s,int t,int a,int b)
{
	for (s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1)
	{
		if (~s&1) add(s^1,a,b,++inum);
		if ( t&1) add(t^1,a,b,++inum);
	}
}

int n,m,P;
int dis[N];

int Q[N],l,r;
//set<int> Set;
//typedef set<int>::iterator ITER;
int Stk[N],pnt;

int fat[N];
int Fat(int u){
	return u==fat[u]?u:fat[u]=Fat(fat[u]);
}

int main()
{
	int a,b,c,d,u;
//	ITER it;
	freopen("t.in","r",stdin);
	freopen("t.out","w",stdout);
	read(n); read(m); read(P);
	Build(n);
	for (int i=1;i<=m;i++)
	{
		read(a); read(b); read(c); read(d);
		insert(a,b,c,d); insert(c,d,a,b);
	}
	l=r=-1; Q[++r]=P; dis[P]=0;
//	for (int i=1;i<=n;i++) if (i!=P) Set.insert(i);
	for (int i=1;i<=n+1;i++) fat[i]=i;
	fat[P]=P+1;
	while (l<r)
	{
		int u=Q[++l];
		for (int t=M+u;t;head[t]=0,t>>=1)
			for (int p=head[t];p;p=G[p].next)
			{
//				for (pnt=0,it=Set.lower_bound(G[p].l);it!=Set.end() && *it<=G[p].r;it++)
//					dis[*it]=dis[u]+1,Q[++r]=*it,Stk[++pnt]=*it;
				pnt=0;
				for (int i=Fat(G[p].l);i<=G[p].r;i=Fat(i+1))
					dis[i]=dis[u]+1,Q[++r]=i,Stk[++pnt]=i;
//				while (pnt) Set.erase(Stk[pnt--]);
				while (pnt) fat[Stk[pnt]]=Stk[pnt]+1,pnt--;
			}
	}
	for (int i=1;i<=n;i++) printf("%d\n",dis[i]);
	return 0;
时间: 2024-10-09 17:58:56

[线段树建图 bfs] BZOJ 3073 [Pa2011]Journeys的相关文章

POJ 1436 Horizontally Visible Segments(线段树建图+枚举)

题目连接:http://poj.org/problem?id=1436 题意:给一些线段,每个线段有三个值y1, y2, x代表起点为(x, y1),终点为(x, y2)的线段.当从一个线段可以作水平线到另一个线段并且不穿过其他线段时,就称这两个线段时水平可见的.当三个线段可以两两水平可见,就称为形成一个线段三角.问:在这些线段中有多少个这样的线段三角? 分析:可以把每条线段看做是一个点,如果它和其他线段是水平可见的,就将这两个点相连,由于是无向图,就是你能看到我,我也能看到你,所以需要连接两次

HDU5669 Road 分层最短路+线段树建图

分析:(官方题解) 首先考虑暴力,显然可以直接每次O(n^2) ?的连边,最后跑一次分层图最短路就行了. 然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维护整个图, 连边时候找到对应区间,把线段树的节点之间连边.这样可以大大缩减边的规模,然后再跑分层图最短路就可以了. 但是这样建图,每一次加边都要在O(logn)个线段树节点上加边,虽然跑的非常快,但是复杂度仍然是不科学的. 为了解决边的规模的问题,开两棵线段树,连边时候可以新建一个中间节点,在对应区

线段树建图

对于一个图,n个节点,有向边,求点s到其他所有点的最短路. 题目给的边的方式: u -> v [l,r] -> v v -> [l,r] 这样的话边数是O(n^2)级别的,怎么做? 假设把[1,n]建成segment tree 后,有tot个节点. 则建一个新图,新图有2 * tot + n个节点 新图多了2 * tot个节点,表示2棵线段树A,B 点的编号分类: A - [1,tot] B - [tot + 1,2 * tot] C - [2 * tot + 1,2 * tot + n

BZOJ 1018 线段树维护图的连通性问题

思路: 我们可以搞一棵线段树 对于一段区间有6种情况需要讨论 左上右下.左上右上.左下右下.左下右上 这四种比较好维护 用左上右下举个例子吧 就是左儿子的左上右下&左区间到右区间下面有路&右儿子的左下右下 或者是左儿子的左上右上&左区间到右区间上面有路&右儿子的左上右下 还有两种  区间的左(右)端点上下能不能联通 需要维护 这种就是左儿子的上下连通或(左上右上&左上右下&左到右两条路都联通&右儿子的上下联通) (假设c1<c2) 最后要查的是

CF-787D-线段树建图+最短路

http://codeforces.com/problemset/problem/787/D 题目大意是给出一个有向图,有N个节点,初始节点在S,询问S到所有点最短路.边的读入方式有三种, 1 u v w  表示 u->v有一条边权为w的边, 2 v l r w ,表示v->[l,r]内的任意一个点支付w即可, 3 v l r w 表示从[l,r]内任意一个点到v支付w即可.直接构图的话可能会出现完全图,被卡死. 一种巧妙的构图方式是,由这些个区间联想到线段树(然而我并没有想到),我们不妨对2

BZOJ 1018 线段树维护图连通性

用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可. Side表示这一块有没有接到右边.Merge一下就可以了.码农题,WA了一次,发现未初始化,就AC了.. 1 #include <cstdio> 2 inline int Min(int x,int y) {return x>y?y:x;} 3 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;} 4

codeforces gym #101987B -Cosmetic Survey(建图+bfs思维)

题目链接: https://codeforces.com/gym/101987/attachments 题意: 给出$n$个节点,$m$条边 对于所有$(a,b)$,求出$a$到$b$路径中最小边的最大值 注意两个隐藏条件 1.不存在环 2.如果$a$到$b$,$b$到$c$,那么$len(a,b)>len(b,c)$ 数据范围: $1\leq n \leq 500$ $1\leq m \leq 250000$ 分析: 一条路径最小值 AC代码: #include<bits/stdc++.h&

codevs 2216 行星序列 线段树+延迟标记(BZOJ 1798)

2216 行星序列 时间限制: 2 s 空间限制: 256000 KB 题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小宇航员夏令营”,在这里小可可不仅学到了丰富的宇航知识,还参与解决了一些模拟飞行中发现的问题,今天指导老师交给他一个任务,在这次模拟飞行的路线上有N个行星,暂且称它们为一个行星序列,并将他们从1至n标号,在宇宙未知力量的作用下这N个行星的质量是不断变化的,所以他们对飞船产生的引力也会不断变化,

NYOJ 20 吝啬的国度 【BFS+链式前向星建图,Vector建图】

吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路). 输入 第一行输入一个整数M表示测试数据共有M(1<=M<=5)组 每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<=S<=100000