[MST][dij]JZOJ 5818 做运动
分析
这题可以对温度搞一个最小生成树,在最小生成图上跑堆优化dij就行了
#pragma GCC optimize(3) #include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> #include <queue> #include <memory.h> using namespace std; typedef long long ll; const int N=5e5+1; const ll Inf=9223372036854775807; struct Edge { int u,v,nx; ll t,w; }g[4*N]; int cnt,list[N]; ll d[N],temp; bool b[N]; int f[N],r[N]; int n,m,s,t; inline int Get_F(int x) {return x==f[x]?x:Get_F(f[x]);} inline void Merge(int x,int y) { int i=Get_F(x),j=Get_F(y); if (r[i]<r[j]) r[j]=max(r[i]+1,r[j]),f[i]=j; else r[i]=max(r[j]+1,r[i]),f[j]=i; } inline void Add(int u,int v,ll t,ll w) {g[++cnt].u=u;g[cnt].v=v;g[cnt].t=t;g[cnt].w=w;g[cnt].nx=list[u];list[u]=cnt;} bool Cmp(Edge a,Edge b) {return a.t<b.t;} inline int Read() { char c=getchar();int num=0,p=1; while (c>'9'||c<'0') { if (c=='0') p=-1; c=getchar(); } while ('0'<=c&&c<='9') { num=num*10+c-'0'; c=getchar(); } return num*p; } void Dij() { priority_queue <int> q; while (!q.empty()) q.pop(); for (int i=1;i<=n;i++) d[i]=Inf; q.push(s);d[s]=0; while (!q.empty()) { int u=q.top();q.pop(); // if (b[u]) continue; // b[u]=1; for (int i=list[u];i;i=g[i].nx) if (/*!b[g[i].v]&&*/d[g[i].v]>d[u]+g[i].w&&g[i].t<=temp) { d[g[i].v]=d[u]+g[i].w; q.push(g[i].v); } } } int main() { freopen("running.in","r",stdin); freopen("running.out","w",stdout); n=Read();m=Read(); for (int i=0;i<m;i++) { int u,v; ll t,c; u=Read();v=Read();t=1ll*Read();c=1ll*Read(); Add(u,v,t,t*c);Add(v,u,t,t*c); } s=Read();t=Read(); memset(list,0,sizeof list); sort(g+1,g+cnt+1,Cmp); for (int i=1;i<=cnt;i++) g[i].nx=list[g[i].u],list[g[i].u]=i; for (int i=1;i<=n;i++) f[i]=i,r[i]=1; for (int i=1;i<=cnt;i++) if (Get_F(g[i].u)!=Get_F(g[i].v)) { Merge(g[i].u,g[i].v); temp=g[i].t; if (Get_F(s)==Get_F(t)) break; } Dij(); printf("%lld %lld",temp,d[t]); fclose(stdin);fclose(stdout); }
在日渐沉没的世界里,我发现了你。