总体思想是,使用线段树思想,用点和区间进行连边,只有当一个区间已经是最小值时才更新该区间内所有的点;具体思路参照这里:洛谷
代码实现:
#include<bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
#define lc(x) (x << 1)
#define rc(x) ((x << 1) | 1)
const int N = 1e5 + 5;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
ll fast_pow(ll a,ll b){ll ans = 1;while(b){if(b&1)ans = (ans * a)%mod;a = (a * a)%mod;b>>=1;}return (ans%mod);}
inline ll read(){ll X=0; bool flag=1; char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}if(flag) return X;return ~(X-1);}
inline void write(ll X){if(X<0) {X=~(X-1); putchar('-');}if(X>9) write(X/10);putchar(X%10+'0');}
typedef pair<int,int> pii;
typedef vector<int> vi;
inline void fastIO(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
inline void time_cost(clock_t start_time,clock_t end_time){cout << "The run time is: " <<(double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << endl;}
inline void init(){
}
int n,q,s;
const int D = 5e5;
ll dis[1000005];
vector<pair<int,int> > g[1000005];
int leaf[N];
void build(int x,int l,int r){
if(l == r){
leaf[l] = x;
return;
}
int mid = (l + r) >> 1;
g[x].pb(mp(lc(x),0)),g[x].pb(mp(rc(x),0));
g[lc(x) + D].pb(mp(x + D,0)),g[rc(x) + D].pb(mp(x + D,0));
build(lc(x),l,mid);
build(rc(x),mid + 1,r);
}
void connect(int x,int curl,int curr,int u,int ql,int qr,int w,int type){
if(ql <= curl && qr >= curr){
if(type % 2)
g[x + D].pb(mp(leaf[u],w));
else
g[leaf[u] + D].pb(mp(x,w));
return;
}
int mid = (curl + curr) >> 1;
if(qr <= mid)
connect(lc(x),curl,mid,u,ql,qr,w,type);
else if(ql > mid)
connect(rc(x),mid + 1,curr,u,ql,qr,w,type);
else
connect(lc(x),curl,mid,u,ql,qr,w,type),connect(rc(x),mid + 1,curr,u,ql,qr,w,type);
}
inline void solve(){
init();
cin >> n >> q >> s;
build(1,1,n);
for(int i = 1;i <= n;i++)g[leaf[i]].pb(mp(leaf[i] + D,0)),g[leaf[i] + D].pb(mp(leaf[i],0));
for(int i = 1;i <= q;i++){
int opt,u,v,w,l,r;
cin >> opt;
if(opt == 1){
cin >> u >> v >> w;
g[leaf[u] + D].pb(mp(leaf[v],w));
}else{
cin >> u >> l >> r >> w;
connect(1,1,n,u,l,r,w,opt % 2);
}
}
priority_queue<pair<ll,int>,vector<pair<ll,int> >, greater<pair<ll,int> > > q;
q.push(mp(0LL,leaf[s] + D));
memset(dis,0x3f,sizeof(dis));
dis[leaf[s] + D] = 0;
while(!q.empty()){
auto p = q.top();
q.pop();
ll tmp = p.fi,u = p.se;
if(tmp > dis[u])continue;
for(auto pp : g[u]){
int v = pp.fi;
ll w = pp.se;
if(dis[u] + w < dis[v]){
dis[v] = dis[u] + w;
q.push(mp(dis[v],v));
}
}
}
for(int i = 1;i <= n;i++){
if(dis[leaf[i]] == INF)
cout << "-1 ";
else
cout << dis[leaf[i]] <<" ";
}
}
int main(){
fastIO();
#if DBG
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
solve();
return 0;
}