NC20131. [JLOI2011]飞行路线
描述
输入描述
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0 ≤ s,t < n)接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0 ≤ a,b < n,a与b不相等,0 ≤ c ≤ 1000)对于30%的数据,2<=n<=50,1<=m<=300,k=0;
对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;
对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.
输出描述
只有一行,包含一个整数,为最少花费。
示例1
输入:
5 6 1 0 4 0 1 5 1 2 5 2 3 5 3 4 5 2 3 3 0 2 100
输出:
8
C++14(g++5.4) 解法, 执行用时: 175ms, 内存消耗: 56524K, 提交时间: 2020-06-01 10:00:59
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=4000010; int n,m,k,s,t,dist[N]; int h[N],e[N],ne[N],w[N],idx; void add(int a,int b,int c) { e[idx]=b; w[idx]=c; ne[idx]=h[a]; h[a]=idx++; } bool st[N]; void dij() { priority_queue<pii,vector<pii>,greater<pii> > q; q.push({0,s}); dist[s]=0; while(q.size()) { int u=q.top().second; q.pop(); if(st[u]) continue; st[u]=1; for(int i=h[u];i!=-1;i=ne[i]) { int v=e[i]; if(!st[v]&&dist[v]>dist[u]+w[i]) { dist[v]=dist[u]+w[i]; q.push({dist[v],v}); } } } } int main() { memset(h,-1,sizeof h); memset(dist,0x3f,sizeof dist); scanf("%d%d%d%d%d",&n,&m,&k,&s,&t); for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); for(int j=0;j<=k;j++) { add(a+j*n,b+j*n,c); add(b+j*n,a+j*n,c); if(j!=k) { add(a+j*n,b+(j+1)*n,0); add(b+j*n,a+(j+1)*n,0); } } } dij(); int ans=0x3f3f3f3f; for(int i=0;i<=k;i++) ans=min(dist[t+i*n],ans); cout<<ans; return 0; }
C++(g++ 7.5.0) 解法, 执行用时: 162ms, 内存消耗: 36888K, 提交时间: 2022-09-05 14:00:20
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+5,M=6e6+6; struct edge{ int to,nx; ll v; }e[M*2]; int hd[N],tot; void add(int x,int y,int z){ e[++tot]={y,hd[x],z};hd[x]=tot; } ll dis[N]; bool vis[N]; priority_queue<pair<ll,int>>q; void dij(int s){ memset(dis,0x3f,sizeof dis); q.push({0,s}); dis[s]=0; while(q.size()){ int x=q.top().second;q.pop(); if(vis[x])continue; vis[x]=1; for(int i=hd[x];i;i=e[i].nx){ int y=e[i].to; if(dis[x]+e[i].v<dis[y]){ dis[y]=dis[x]+e[i].v; q.push({-dis[y],y}); } } } } int n,m,k,s,t; int main(){ scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&s,&t); for(int i=1;i<=m;++i){ int x,y,z;scanf("%d%d%d",&x,&y,&z); for(int j=0;j<=k;++j){ add(j*n+x,j*n+y,z); add(j*n+y,j*n+x,z); } for(int j=0;j<k;++j){ add(j*n+x,(j+1)*n+y,0); add(j*n+y,(j+1)*n+x,0); } } for(int i=0;i<n;++i){ for(int j=0;j<k;++j){ add(j*n+i,(j+1)*n+i,0); } } dij(s); ll ans=dis[k*n+t]; printf("%lld\n",ans); }
C++(clang++ 11.0.1) 解法, 执行用时: 340ms, 内存消耗: 55972K, 提交时间: 2023-07-31 20:30:06
#include<bits/stdc++.h> #define N 200005 #define int long long using namespace std; int n,m,k,dis[N],s,t,res=1e18; typedef pair<int,int> PII; bool vis[N]; struct node{ int v,w; }; vector<node> g[N]; void dijkstra(){ memset(dis,0x3f,sizeof(dis)); dis[s]=0; priority_queue<PII,vector<PII>,greater<PII>> pq; pq.push({0,s}); while(pq.size()){ auto K=pq.top(); int t=K.second; pq.pop(); if(vis[t]) continue; vis[t]=1; for(auto [j,w]:g[t]){ if(dis[j]>dis[t]+w){ dis[j]=dis[t]+w; pq.push({dis[j],j}); } } } } signed main(){ cin>>n>>m>>k>>s>>t; s++,t++; for(int i=1;i<=m;i++){ int x,y,z; cin>>x>>y>>z; x++,y++; g[x].push_back({y,z}); g[y].push_back({x,z}); for(int j=1;j<=k;j++){ g[j*n+x].push_back({j*n+y,z}); g[j*n+y].push_back({j*n+x,z}); g[(j-1)*n+x].push_back({j*n+y,0}); g[(j-1)*n+y].push_back({j*n+x,0}); } } dijkstra(); for(int i=0;i<=k;i++) res=min(res,dis[i*n+t]); cout<<res; }