题目链接:https://codeforces.com/contest/787/problem/B
题目给出三种询问,如果暴力建边很显然复杂度过大,参考线段树优化建边,加虚点即可完成
参考博文:https://www.luogu.org/blog/chengni5673/tu-lun-di-xiao-ji-qiao-yi-ji-kuo-zhan
#include <bits/stdc++.h>
#define pii pair<ll, ll>
#define pil pair<ll, long long>
#define pll pair<long long, long long>
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define ls (k << 1)
#define rs (k << 1 | 1)
using namespace std;
typedef long long ll;
template <typename T>
inline void read(T &X) {
X = 0; char ch = 0; T op = 1;
for(; ch > '9' || ch < '0'; ch = getchar())
if(ch == '-') op = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar())
X = (X << 3) + (X << 1) + ch - 48;
X *= op;
}
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll N = 5e5 + 5;
struct edge {
ll u,v,w,next;
}e[N << 2];
struct node {
ll num[N];
}tr[2];
ll vis[N],dis[N],cnt,head[N];
ll n,q,s,now;
void insert(ll u, ll v, ll w) {
e[++cnt] = {u, v, w, head[u]}; head[u] = cnt;
}
void dijkstra() {
priority_queue<pii, vector<pii>, greater<pii> > q;
mem(dis, INF);
q.push(make_pair(0, s)); dis[s] = 0;
while(!q.empty()) {
ll u = q.top().second; q.pop();
if(vis[u]) continue; vis[u] = 1;
for(ll i = head[u]; i ; i = e[i].next) {
ll v = e[i].v;
if(dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
q.push(make_pair(dis[v], v));
}
}
}
return;
}
void build(ll k, ll l, ll r, ll p) {
if(l == r) {
tr[p].num[k] = l;
return;
}
tr[p].num[k] = ++now;
ll mid = l + r >> 1;
build(ls, l, mid, p);
build(rs, mid + 1, r, p);
if(p == 0) {
insert(tr[p].num[k], tr[p].num[ls], 0);
insert(tr[p].num[k], tr[p].num[rs], 0);
} else {
insert(tr[p].num[ls], tr[p].num[k], 0);
insert(tr[p].num[rs], tr[p].num[k], 0);
}
}
void find(ll k, ll l, ll r, ll s, ll t, ll p, ll u, ll w) {
if(s <= l && t >= r) {
if(p == 0) insert(u, tr[p].num[k], w);
else insert(tr[p].num[k], u, w);
return;
}
ll mid = l + r >> 1;
if(s <= mid) find(ls, l, mid, s, t, p, u, w);
if(t > mid) find(rs, mid + 1, r, s, t, p, u, w);
return;
}
int main() {
#ifdef INCTRY
freopen("input.txt", "rt", stdin);
#endif
cin >> n >> q >> s;
now = n;
build(1, 1, n, 0); build(1, 1, n, 1);
while(q--) {
ll t,u,v,w,c,l,r;
read(t);
//cout << q << " ";
if(t == 1) {
read(u); read(v); read(w);
insert(u, v, w);
} else {
read(u); read(l); read(r); read(w);
if(t == 2) {
find(1, 1, n, l, r, 0, u, w);
} else {
find(1, 1, n, l, r, 1, u, w);
}
}
}
dijkstra();
for(ll i = 1; i <= n; i++) {
cout << (dis[i] == INF ? -1 : dis[i]) << " " ;
}
#ifdef INCTRY
cerr << "\nTime elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}