1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#include<bits/stdc++.h> using namespace std;
using i64=long long;
const i64 INF=0x3f3f3f3f3f3f3f3f; const int N=2e5+5; const int M=1e9+5;
struct Line{ i64 k; i64 b; Line(){} Line(i64 _k,i64 _b){ k=_k; b=_b; } i64 val(int x){ return k*x+b; } }; struct Seg_Tree{ int tot; int rt[N]; int lc[N<<5]; int rc[N<<5]; Line line[N<<5]; int addnode(){ tot++; lc[tot]=rc[tot]=0; line[tot]=Line(0,INF); return tot; } void insert(int &x,int l,int r,int ql,int qr,Line li){ if(!x) x=addnode(); int mid=l+r>>1; if(l>=ql&&r<=qr){ if(li.val(l)<=line[x].val(l)&&li.val(r)<=line[x].val(r)){ line[x]=li; return; } else if(li.val(l)>line[x].val(l)&&li.val(r)>line[x].val(r)) return; else{ insert(lc[x],l,mid,ql,qr,li); insert(rc[x],mid+1,r,ql,qr,li); } return; } if(mid>=ql) insert(lc[x],l,mid,ql,qr,li); if(mid+1<=qr) insert(rc[x],mid+1,r,ql,qr,li); } void search(int x,int l,int r,int pos,i64 &res){ if(!x) return; res=min(res,line[x].val(pos)); if(l==r) return; int mid=l+r>>1; if(pos<=mid) search(lc[x],l,mid,pos,res); else search(rc[x],mid+1,r,pos,res); } }tr;
int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
int n,m; cin>>n>>m;
vector<array<int,4>> edge(m,{0,0,0,0}); for(auto &[a,b,c,d]:edge) cin>>a>>b>>c>>d;
sort(edge.begin(),edge.end(),[&](const array<int,4> &x,const array<int,4> &y){ if(x[3]!=y[3]) return x[3]<y[3]; else return x[2]<y[2]; });
i64 ans=INF; tr.insert(tr.rt[1],0,M,0,M,Line(0,0)); for(auto [a,b,c,d]:edge){ i64 res=INF; tr.search(tr.rt[a],0,M,c,res); if(res==INF) continue; res+=1ll*c*c; if(b==n) ans=min(ans,res); else tr.insert(tr.rt[b],0,M,d,M,Line(-2ll*d,res+1ll*d*d)); }
if(ans==INF) cout<<"-1"; else cout<<ans;
return true&&false; }
|