bzoj2763 [JLOI2011]飞行路线——分层图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763
构建分层图。
代码如下:
写法1(空间略大)(时间很慢):
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; priority_queue<pair<int,int> >q; int const maxn=2e5+5,maxm=1500005; int n,m,k,s,t,head[maxn],ct,dis[maxn]; bool vis[maxn]; struct N{ int to,next,w; N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {} }edge[maxm<<1]; void add(int x,int y,int z) { edge[++ct]=N(y,head[x],z); head[x]=ct; edge[++ct]=N(x,head[y],z); head[y]=ct; for(int i=0;i<=k-1;i++) { int u=x+i*n,v=y+(i+1)*n; edge[++ct]=N(v,head[u],0); head[u]=ct; u=y+i*n,v=x+(i+1)*n; edge[++ct]=N(v,head[u],0); head[u]=ct; u=x+(i+1)*n,v=y+(i+1)*n; edge[++ct]=N(v,head[u],z); head[u]=ct; edge[++ct]=N(u,head[v],z); head[v]=ct; } } void dijkstra() { memset(dis,0x3f,sizeof dis); dis[s]=0; q.push(make_pair(0,s)); while(q.size()) { int x=q.top().second; q.pop(); while(vis[x]&&q.size())x=q.top().second,q.pop(); if(vis[x])break; vis[x]=1; for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(dis[u]>dis[x]+edge[i].w) { dis[u]=dis[x]+edge[i].w; q.push(make_pair(-dis[u],u)); } } } } int main() { scanf("%d%d%d%d%d",&n,&m,&k,&s,&t); t+=k*n; for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); } dijkstra(); printf("%d",dis[t]); return 0; }
写法2(空间小)(时间飞快)(bfs)(dijkstra?):
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int const maxn=10005,maxm=50005; struct P{ int bh,d,f; P(int b=0,int d=0,int f=0):bh(b),d(d),f(f) {} bool operator < (const P &y) const { return d>y.d;//priority_queue 是从大到小排序 } }; priority_queue<P>q; int n,m,K,head[maxn],ct,s,t,dis[maxn][15]; bool vis[maxn][15]; struct N{ int to,next,w; N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {} }edge[maxm<<1]; void add(int x,int y,int z){edge[++ct]=N(y,head[x],z); head[x]=ct;} void bfs() { memset(dis,0x3f,sizeof dis); dis[s][0]=0; q.push(P(s,0,0)); while(q.size()) { int x=q.top().bh, d=q.top().d, f=q.top().f; q.pop(); if(vis[x][f])continue; vis[x][f]=1; if(x==t) { printf("%d",d); return; } for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(f<K&&dis[u][f+1]>d&&!vis[u][f+1]) { dis[u][f+1]=d; q.push(P(u,d,f+1)); } if(dis[u][f]>d+edge[i].w&&!vis[u][f]) { dis[u][f]=d+edge[i].w; q.push(P(u,dis[u][f],f)); } } } } int main() { scanf("%d%d%d%d%d",&n,&m,&K,&s,&t); for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } bfs(); return 0; }