【題解】Vijos1404 遭遇戰(最短路圖論套路)
感覺一定要有建模的思想,不管什麼東西要抽象建模之後再用算法解決...
求最短代價就可能可以用最短路,這句話不是強行解釋,而是因爲圖論建模過後,可能存在很多不合法的情況,但是由於我們只是求最短路,所以我們只要保證對於每一條最短路可以構造一個與之對應的合法原問題解
給你一條數軸和 m 條線段,第 i 條線段覆蓋區間 [Li,Ri] ,選擇它需要代價 Ci 。
請選出代價和最小的一組線段使得區間 [L,R] 中的每一段都被覆蓋。
考慮建立這些有向邊:\((L_i,R_i+1,C_i),(x,x-1,0)\)
考慮對於一個最短路,構造方案就是這條最短路經過的所有\(i\)選上即可。
充分性和必要性都挺顯然的,因爲(不繞環的)路徑和原問題的解可以一一對應,而一定存在一條最短路使得整條最短路沒有環。
加1的原因是我們只要整點覆蓋
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std; typedef long long ll; char __buf[1<<18],*__c=__buf,*__ed=__buf;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=9e4+5;
const int inf=0x3f3f3f3f;
int d[maxn];
struct E{int to,w;};
vector<E> e[maxn];
typedef pair<int,int> P;
priority_queue<P,vector<P>,greater<P> > q;
inline void add(const int&fr,const int&to,const int&w){e[fr].push_back({to,w});}
int n,L,R;
inline void dij(){
memset(d,0x3f,sizeof d);
q.push({d[L]=0,L});
while(q.size()){
auto g=q.top();
q.pop();
if(g.first>d[g.second]) continue;
for(auto t:e[g.second])
if(d[t.to]>g.first+t.w)
q.push({d[t.to]=g.first+t.w,t.to});
}
}
int main(){
n=qr(); L=qr(); R=qr();
for(int t=1,t1,t2,v;t<=n;++t){
t1=max(L,qr()),t2=min(qr()+1,R+1);
add(t1,t2,v=qr());
add(t2,t1,v);
}
for(int t=L+1;t<=R+1;++t) add(t,t-1,0);
dij();
if(d[R+1]!=d[0]) printf("%d\n",d[R+1]);
else puts("-1");
return 0;
}