动态加点的spfa
#include<ctime>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 50500
using namespace std;
struct abcd{
int to,f,next;
}table[M<<2];
int head[M],tot;
struct edges{
int x,y,a,b;
}e[M<<1];
bool operator <(edges x,edges y)
{
return x.a < y.a ;
}
int n,m,ans=0x3f3f3f3f,f[M],heap[M],pos[M],top;
void push_up(int x)
{
int t=pos[x];
while(t>1&&f[heap[t]]<f[heap[t>>1]])
swap(heap[t],heap[t>>1]),swap(pos[heap[t]],pos[heap[t>>1]]),t>>=1;
}
void insert(int x)
{
heap[++top]=x;
pos[x]=top;
push_up(x);
}
void pop()
{
pos[heap[1]]=0;
heap[1]=heap[top];
heap[top--]=0;
pos[heap[1]]=1;
int t=2;
while(t<=top)
{
if(t<top&&f[heap[t]]>f[heap[t+1]])
t++;
if(f[heap[t]]<f[heap[t>>1]])
swap(heap[t],heap[t>>1]),swap(pos[heap[t]],pos[heap[t>>1]]),t<<=1;
else
break;
}
}
void SPFA()
{
int i;
while(top)
{
int x=heap[1];pop();
for(i=head[x];i;i=table[i].next)
if(f[table[i].to]>max(f[x],table[i].f))
{
f[table[i].to]=max(f[x],table[i].f);
if(!pos[table[i].to])
insert(table[i].to);
else
push_up(table[i].to);
}
}
}
void add(int x,int y,int z)
{
table[++tot].to=y;
table[tot].f=z;
table[tot].next=head[x];
head[x]=tot;
}
char c;
inline void scan(int &x)
{
x=0;
do c=getchar(); while(c<'0'||c>'9');
while(c>='0'&&c<='9')x*=10,x+=c-'0',c=getchar();
}
int main()
{
//freopen("forest.in","r",stdin);
//freopen("forest.out","w",stdout);
int i;
cin>>n>>m;
for(i=1;i<=m;i++)
scan(e[i].x),scan(e[i].y),scan(e[i].a),scan(e[i].b);
sort(e+1,e+m+1);
memset(f,0x3f,sizeof f);
f[1]=0;
for(i=1;i<=m;i++)
{
add(e[i].x,e[i].y,e[i].b);
add(e[i].y,e[i].x,e[i].b);
if(f[e[i].x]>f[e[i].y])
swap(e[i].x,e[i].y);
if(max(f[e[i].x],e[i].b)<f[e[i].y])
f[e[i].y]=max(f[e[i].x],e[i].b),insert(e[i].y);
if(e[i].a!=e[i+1].a)
SPFA();
ans=min(ans,e[i].a+f[n]);
}
if(ans==0x3f3f3f3f)
cout<<-1<<endl;
else
cout<<ans<<endl;
return 0;
}