[HDU5361]In Touch

[HDU5361]In Touch

题目大意:

\(n(n\le2\times10^5)\)个点,每个点有三个属性\(l_i,r_i,c_i\)。表示若\(|i-j|\in[l_i,r_i]\)\(i\)\(j\)有一条长度为\(c_i\)的单向边。求从\(1\)出发到各个点的距离。

思路:

线段树优化建图后跑Dijkstra即可。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<functional>
#include<ext/pb_ds/priority_queue.hpp>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=4e5+1;
typedef long long int64;
int tot,l[N],r[N],c[N],pos[N];
struct Edge {
	int to,w;
};
std::vector<Edge> e[N];
inline void add_edge(const int &u,const int &v,const int &w) {
	e[u].push_back((Edge){v,w});
}
inline void reset() {
	for(register int i=1;i<=tot;i++) {
		e[i].clear();
	}
	tot=0;
}
class SegmentTree {
	#define mid ((b+e)>>1)
	private:
		struct Node {
			int left,right;
		};
		Node node[N];
		int new_node() {
			node[++tot]=(Node){};
			return tot;
		}
	public:
		int root;
		void build(int &p,const int &b,const int &e) {
			p=new_node();
			if(b==e) {
				pos[b]=p;
				return;
			}
			build(node[p].left,b,mid);
			build(node[p].right,mid+1,e);
			add_edge(p,node[p].left,0);
			add_edge(p,node[p].right,0);
		}
		void link(const int &p,const int &b,const int &e,const int &l,const int &r,const int &x,const int &y) const {
			if(l>r) return;
			if(b==l&&e==r) {
				add_edge(x,p,y);
				return;
			}
			if(l<=mid) link(node[p].left,b,mid,l,std::min(mid,r),x,y);
			if(r>mid) link(node[p].right,mid+1,e,std::max(mid+1,l),r,x,y);
		}
	#undef mid
};
SegmentTree sgt;
struct Vertex {
	int id;
	int64 dis;
	bool operator > (const Vertex &rhs) const {
		return dis>rhs.dis;
	}
};
int64 dis[N];
__gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
__gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[N];
inline void dijkstra() {
	for(register int i=1;i<=tot;i++) {
		p[i]=q.push((Vertex){i,dis[i]=i==pos[1]?0:LLONG_MAX});
	}
	while(!q.empty()&&q.top().dis!=LLONG_MAX) {
		const int x=q.top().id;
		q.pop();
		for(register unsigned i=0;i<e[x].size();i++) {
			const int &y=e[x][i].to,&w=e[x][i].w;
			if(dis[x]+w<dis[y]) {
				q.modify(p[y],(Vertex){y,dis[y]=dis[x]+w});
			}
		}
	}
	q.clear();
}
int main() {
	for(register int T=getint();T;T--) {
		const int n=getint();
		sgt.build(sgt.root,1,n);
		for(register int i=1;i<=n;i++) l[i]=getint();
		for(register int i=1;i<=n;i++) r[i]=getint();
		for(register int i=1;i<=n;i++) c[i]=getint();
		for(register int i=1;i<=n;i++) {
			sgt.link(1,1,n,std::max(1,i-r[i]),i-l[i],pos[i],c[i]);
			sgt.link(1,1,n,i+l[i],std::min(i+r[i],n),pos[i],c[i]);
		}
		dijkstra();
		for(register int i=1;i<=n;i++) {
			printf("%lld%c",dis[pos[i]]!=LLONG_MAX?dis[pos[i]]:-1," \n"[i==n]);
		}
		reset();
	}
	return 0;
}
posted @ 2018-09-27 12:53  skylee03  阅读(133)  评论(0编辑  收藏  举报