题意:
有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 '\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;
}