[最小生成树][Dij] Jzoj P5818 做运动
题解
- 这题首先是满足路径上的最大温度最小的前提下,求最短路
- 那么,先解决路径上最大温度最小,显然可以用最小生成树来做
- 每次就在s和t还未在同一个联通块时,更新最大温度mx
- 然后就解决了第一个问题
- 然后将所有温度小于等于mx的边,加入一个新的图,两点的路径长度就是时间*温度
- 然后就要求两点之间的最短路,Dij即可
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 struct edge {long long x,y,c; long long v;}e[1000010]; 7 struct node {long long to,from,c; long long v;}E[1000010*2]; 8 long long dis[500010],state[500010][2]; 9 long long fa[500010],mx[500010],visit[500010],head[500010],cnt,n,m,s,t; 10 long long read() 11 { 12 long long res=0,zf=1;char c=getchar(); 13 while(!isdigit(c)) { if(c=='-') zf=-1; c=getchar(); } 14 while(isdigit(c)) { res=res*10+c-'0'; c=getchar(); } 15 return res*zf; 16 } 17 void add(long long x,long long y,long long v,long long c) 18 { 19 E[++cnt].to=y; E[cnt].from=head[x]; E[cnt].v=v; E[cnt].c=c; head[x]=cnt; 20 E[++cnt].to=x; E[cnt].from=head[y]; E[cnt].v=v; E[cnt].c=c; head[y]=cnt; 21 } 22 long long getfather(long long x) { return fa[x]==x?x:fa[x]=getfather(fa[x]); } 23 bool cmp(edge a,edge b) { return a.v<a.v||(a.v==a.v&&a.c<b.c); } 24 void kruskal() 25 { 26 sort(e+1,e+m+1,cmp); 27 for (long long i=1;i<=n;i++) fa[i]=i; 28 long long tot=0,mx=0; 29 for (long long i=1;i<=m;i++) 30 { 31 long long u=getfather(e[i].x),v=getfather(e[i].y); 32 if (u!=v) 33 { 34 if (getfather(s)!=getfather(t)) mx=e[i].c; 35 fa[u]=v; 36 tot++; 37 if (tot==n-1) break; 38 } 39 } 40 printf("%lld ",mx); 41 for (long long i=1;i<=m;i++) if (e[i].c<=mx) add(e[i].x,e[i].y,e[i].v,e[i].c); 42 } 43 void dijkstra() 44 { 45 memset(visit,0,sizeof(visit)); 46 for (long long i=1;i<=n;i++) dis[i]=1e18; 47 dis[s]=0; 48 long long l=0,r=1; 49 state[1][1]=0,state[1][2]=s; 50 while (l<r) 51 { 52 l++; 53 long long u=state[l][2]; 54 if (visit[u]) continue; 55 visit[u]=1; 56 for (long long i=head[u];i;i=E[i].from) 57 { 58 long long v=E[i].to; 59 if (dis[v]>dis[u]+E[i].v) 60 { 61 dis[v]=dis[u]+E[i].v; 62 r++; 63 state[r][1]=dis[v],state[r][2]=v; 64 } 65 } 66 } 67 printf("%lld",dis[t]); 68 } 69 int main() 70 { 71 freopen("running.in","r",stdin); 72 freopen("running.out","w",stdout); 73 n=read(),m=read(); 74 for (long long i=1;i<=m;i++) 75 { 76 long long a=read(),b=read(),t=read(),c=read(); 77 e[i].x=a,e[i].y=b,e[i].v=(long long)t*c,e[i].c=t; 78 } 79 s=read(),t=read(); 80 kruskal(),dijkstra(); 81 fclose(stdin); fclose(stdout); 82 return 0; 83 }