1. 程式人生 > >codeforces 787D - Legacy 線段樹優化建圖,最短路

codeforces 787D - Legacy 線段樹優化建圖,最短路

題意:

有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也都出過,

還是要見識一下的...

程式碼如下:

#include <bits/stdc++.h>
#define endl '\n'
#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;
}