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;
    }
    
  • 相关阅读:
    TL 重构
    eclipse中使用Lombok
    一个成功的 Git 分支模型
    《重构,改善既有代码的设计》读书笔记
    重构——改善既有代码的设计
    安装Mysql5.7并修改初始密码
    支付宝支付-PC电脑网站支付
    sqlite3 线程模型
    sqlite 常用的一些语句
    Electron 入门第一篇
  • 原文地址:https://www.cnblogs.com/skylee03/p/9712469.html
Copyright © 2011-2022 走看看