• codeforces 787D


    题意:

    有n个点,q个询问,

    每次询问有一种操作。

    操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w;

    操作2:[l,r]→u的距离为w

    操作3:u到v的距离为w

    最终求起点到其他点的最短距离,到达不了输出-1

    题解

    线段树优化建图+最短路...

    不知道这种东西,百度了一下,好像最早的是POI2015的PUS,然后2017/2018的oi也都出过,

    还是要见识一下的...

    顺便记录一下,封装好的djisktra和graph

    代码如下:

    #include <bits/stdc++.h>
    #define endl '
    '
    #define ll long long
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mp make_pair
    #define pii pair<int,int>
    #define all(x) x.begin(),x.end()
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    #define per(ii,a,b) for(int ii=b;ii>=a;--ii)
    #define forn(ii,x) for(int ii=head[x];ii;ii=e[ii].next)
    #pragma GCC optimize("Ofast")
    #define show(x) cout<<#x<<"="<<x<<endl
    #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
    #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
    #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
    #define show5(v,w,x,y,z) cout<<#v<<" "<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
    #define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
    using namespace std;
    const int maxn=1e6+10,maxm=2e6+10;
    const int INF=0x3f3f3f3f;
    const int mod=1e9+7;
    const double PI=acos(-1.0);
    //head
    int casn,n,m,k;
    int num[maxn];
    class graph{
    public:
    	struct edge{
    		int from,to;ll cost;
    		edge(int a,int b,ll c){from=a,to=b,cost=c;}
    	};
    	vector<vector<edge>> node;
    	int ud=0;
    	graph(int n=maxn,int f=0){node.resize(n+2);ud=f;}
    	void add(int a,int b,int c=1){node[a].emplace_back(a,b,c);if(ud)node[b].emplace_back(b,a,c);}
    };
    
    class dijkstra{
    public:
    	struct road{
    		int now;ll dis;
    		road(int a,ll b){now=a,dis=b;}
    		bool operator<(const road &rhs)const{return dis>rhs.dis;}
    	};
    	vector<ll> dis;
    	priority_queue<road>q;
    	ll INF;
    	dijkstra(graph &g,int st){
    		INF=0x3f3f3f3f3f3f3f3f;
    		dis.resize(g.node.size()+1,INF);
    		q.emplace(st,0);
    		dis[st]=0;
    		while(!q.empty()){
    			road t=q.top();q.pop();
    			for(auto e:g.node[t.now]){
    				ll cost=t.dis+e.cost;
    				if(cost<dis[e.to]){
    					dis[e.to]=cost;
    					q.emplace(e.to,cost);
    				}
    			}
    		}
    	}
    };
    
    class segtree{
    public:
    #define nd  node[now]
    #define ndl node[now<<1]
    #define ndr node[now<<1|1]
    	struct segnode {
    		int l,r;int id;
    		int mid(){return (r+l)>>1;}
    		int len(){return r-l+1;}
    	};
    	graph *g;
    	int cnt,flag;
    	vector<segnode> node;
    	vector<int> ff;
    	segtree(int n,graph *x,int y,int id) {
    		g=x;cnt=id;flag=y;
    		node.resize(n<<2|3);
    		maketree(1,n);
    	}
    	void pushup(int now){
    		if(!flag){
    			g->add(nd.id,ndl.id,0);
    			g->add(nd.id,ndr.id,0);
    		}else {
    			g->add(ndl.id,nd.id,0);
    			g->add(ndr.id,nd.id,0);
    		}
    	}
    	void maketree(int s,int t,int now=1){
    		nd={s,t,++cnt};
    		if(s==t){
    			if(!flag) g->add(nd.id,s,0);
    			else g->add(s,nd.id,0);
    			return ;
    		}
    		maketree(s,nd.mid(),now<<1);maketree(nd.mid()+1,t,now<<1|1);
    		pushup(now);
    	}
    	void query(int s,int t){
    		ff.clear();
    		count(s,t);
    	}
    	void count(int s,int t,int now=1){
    		if(s>nd.r||t<nd.l)return ;
    		if(s<=nd.l&&t>=nd.r) {
    			ff.emplace_back(nd.id);
    			return ;
    		}
    		count(s,t,now<<1);count(s,t,now<<1|1);
    	}
    };
    
    int main() {
    	IO;
    	int n,q,s;
    	cin>>n>>q>>s;
    	graph g(n*10);
    	segtree intree(n,&g,1,n);
    	segtree outtree(n,&g,0,intree.cnt);
    	int k,a,b;ll c,d;
    	while(q--){
    		cin>>k;
    		if(k==1){
    			cin>>a>>b>>c;
    			g.add(a,b,c);
    		}else if(k==2){
    			cin>>a>>b>>c>>d;
    			outtree.query(b,c);
    			for(auto &i:outtree.ff) g.add(a,i,d);
    		}else{
    			cin>>a>>b>>c>>d;
    			intree.query(b,c);
    			for(auto &i:intree.ff) g.add(i,a,d);
    		}
    	}
    	dijkstra ne(g,s);
    	rep(i,1,n) cout<<(ne.dis[i]>=ne.INF?-1:ne.dis[i])<<' ';
    	return 0;
    }
    
  • 相关阅读:
    从键盘输入10个数,计算出正数和负数的个数。
    浏览器允许的并发请求资源数 优化
    strict 严格模式
    AMD 和 CMD 的区别
    Canvas
    visual filters 滤镜 ie
    ie 如何判断正在执行的脚本
    async
    富文本编辑器
    检测CSS属性 是否支持
  • 原文地址:https://www.cnblogs.com/nervendnig/p/10231179.html
Copyright © 2020-2023  润新知