不会LCTqwq,看题解似乎SPFA也可以。
把边按a排序,从小到大每加一条边就以b为距离跑一遍SPFA,类似于Kruskal的想法吧……
貌似是个暴力
(luoguLCT模块的题我都快通过了,然而还是不会LCT蛤蛤蛤)
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cctype> #include<queue> #define maxn 50050 #define maxm 500500 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch==‘-‘) f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-‘0‘; ch=getchar(); } return num*f; } struct Edge{ int from,next,to,vala,valb; bool operator <(const Edge a)const{ return vala<a.vala; } }edge[maxm],d[maxm]; int head[maxn],num; inline void add(int from,int to,int vala,int valb){ edge[++num]=(Edge){from,head[from],to,vala,valb}; head[from]=num; } bool vis[maxn]; int dis[maxn]; int n,m; int spfa(int sta,int stb){ queue<int>q; q.push(1); q.push(sta); q.push(stb); memset(vis,0,sizeof(vis)); vis[1]=vis[sta]=vis[stb]=1; while(!q.empty()){ int from=q.front();q.pop(); vis[from]=0; for(int i=head[from];i;i=edge[i].next){ int to=edge[i].to; if(dis[to]<=max(dis[from],edge[i].valb)) continue; dis[to]=max(dis[from],edge[i].valb); if(vis[to]) continue; vis[to]=1; q.push(to); } } return dis[n]; } int main(){ freopen("testdata.in.txt","r",stdin); n=read(),m=read(); for(int i=1;i<=m;++i) d[i]=(Edge){read(),0,read(),read(),read()}; sort(d+1,d+m+1); memset(dis,127/3,sizeof(dis)); dis[1]=0; int ans=0x7fffffff; for(int i=1;i<=m;++i){ add(d[i].from,d[i].to,d[i].vala,d[i].valb); add(d[i].to,d[i].from,d[i].vala,d[i].valb); int now=d[i].vala+spfa(d[i].from,d[i].to); if(now<ans) ans=now; } printf("%d\n",ans==707406379?-1:ans); return 0; }