「JOISC 2020 Day4」治疗计划(线段树+dijkstra最短路)
「JOISC 2020 Day4」治療計劃
description
solution
設(shè)dpi:1?Ridp_i:1-R_idpi?:1?Ri? 都能被救治成功的最小花費
兩個治療方案[Li,Ri],[Lj,Rj][L_i,R_i],[L_j,R_j][Li?,Ri?],[Lj?,Rj?]能夠合并成完整的健康區(qū)間的條件為Ri?Lj+1≥∣Ti?Tj∣R_i-Lj+1\ge |T_i-T_j|Ri??Lj+1≥∣Ti??Tj?∣
最后要合并成[1,n][1,n][1,n]
相當于如果從Li=1L_i=1Li?=1的所有方案出發(fā),如果能與jjj方案合并,則連邊i→cjji\rightarrow^{c_j} ji→cj?j
求到Rj=nR_j=nRj?=n的最短路
-
Ti≥TjT_i\ge T_jTi?≥Tj?
Ri?Lj+1≥Ti?Tj?Ri?Ti+1≥Lj?TjR_i-L_j+1\ge T_i-T_j\Leftrightarrow R_i-T_i+1\ge L_j-T_jRi??Lj?+1≥Ti??Tj??Ri??Ti?+1≥Lj??Tj?
-
Ti<TjT_i<T_jTi?<Tj?
Ri?Lj+1≥Tj?Tj?Ri+Ti+1≥Lj+TjR_i-L_j+1\ge T_j-T_j\Leftrightarrow R_i+T_i+1\ge L_j+T_jRi??Lj?+1≥Tj??Tj??Ri?+Ti?+1≥Lj?+Tj?
以TjT_jTj?為下標建線段樹,維護兩棵線段樹
最短路用dijkstra跑,線段樹可以查找出所有iii的出邊點
因為每個點的花費是一定的,所以一定是當前最短路拓展到該點且僅一次
所以每個點只會被用一次(用了就可以刪掉了)
O(nlog?n)O(n\log n)O(nlogn)
code
#include <queue> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; #define inf 0x7f7f7f7f #define int long long #define maxn 100005 struct node {int t, l, r, c; }cure[maxn]; vector < int > nxt; priority_queue < pair < int, int > > q; int n, m; int dis[maxn];bool cmp( node x, node y ) {return x.t < y.t; }class SegMentTree {private :int t[maxn << 2];public :void build( int num, int l, int r, int k ) {if( l == r ) {t[num] = cure[l].l + k * cure[l].t;return;}int mid = ( l + r ) >> 1;build( num << 1, l, mid, k );build( num << 1 | 1, mid + 1, r, k );t[num] = min( t[num << 1], t[num << 1 | 1] );}void modify( int num, int l, int r, int pos ) {if( l == r ) {t[num] = inf;return;}int mid = ( l + r ) >> 1;if( pos <= mid ) modify( num << 1, l, mid, pos );else modify( num << 1 | 1, mid + 1, r, pos );t[num] = min( t[num << 1], t[num << 1 | 1] );}void query( int num, int l, int r, int L, int R, int k ) {if( L > R || R < l || r < L || t[num] > k ) return;if( l == r ) {nxt.push_back( l );return;}int mid = ( l + r ) >> 1;query( num << 1, l, mid, L, R, k );query( num << 1 | 1, mid + 1, r, L, R, k );} }S, T; signed main() {scanf( "%lld %lld", &n, &m );for( int i = 1;i <= m;i ++ )scanf( "%lld %lld %lld %lld", &cure[i].t, &cure[i].l, &cure[i].r, &cure[i].c );sort( cure + 1, cure + m + 1, cmp );S.build( 1, 1, m, -1 );T.build( 1, 1, m, 1 );for( int i = 1;i <= m;i ++ )if( cure[i].l == 1 ) {dis[i] = cure[i].c;q.push( make_pair( -dis[i], i ) );S.modify( 1, 1, m, i );T.modify( 1, 1, m, i );}while( ! q.empty() ) {int u = q.top().second; q.pop();if( cure[u].r == n ) return ! printf( "%lld\n", dis[u] );nxt.clear();S.query( 1, 1, m, 1, u - 1, cure[u].r - cure[u].t + 1 );T.query( 1, 1, m, u + 1, m, cure[u].r + cure[u].t + 1 );for( int i = 0;i < nxt.size();i ++ ) {int v = nxt[i];dis[v] = dis[u] + cure[v].c;q.push( make_pair( -dis[v], v ) );S.modify( 1, 1, m, v );T.modify( 1, 1, m, v );}}printf( "-1\n" );return 0; }總結(jié)
以上是生活随笔為你收集整理的「JOISC 2020 Day4」治疗计划(线段树+dijkstra最短路)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 真爱背后剧情介绍 真爱背后电视剧
- 下一篇: [APIO2013]机器人(DP+SPF