zoukankan      html  css  js  c++  java
  • [HDU5361]In Touch

    [HDU5361]In Touch

    题目大意:

    (n(nle2 imes10^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," 
    "[i==n]);
    		}
    		reset();
    	}
    	return 0;
    }
    
  • 相关阅读:
    react路由组件&&非路由组件
    react函数式组件(非路由组件)实现路由跳转
    react使用antd组件递归实现左侧菜单导航树
    【LeetCode】65. Valid Number
    【LeetCode】66. Plus One (2 solutions)
    【LeetCode】68. Text Justification
    【LeetCode】69. Sqrt(x) (2 solutions)
    【LeetCode】72. Edit Distance
    【LeetCode】73. Set Matrix Zeroes (2 solutions)
    【LeetCode】76. Minimum Window Substring
  • 原文地址:https://www.cnblogs.com/skylee03/p/9712469.html
Copyright © 2011-2022 走看看