HDU 4725 The Shortest Path in Nya Graph(优先队列+dijkstra)
题意:n个点、m条边、层与层之间的花费为c,给出每个点所在层(同一层的点联通花费为0),m条边每条边的花费,求1到n的最小花费;
思路:第一反应就是优先队列的dijkstra,层与层之间建边,点与点之间建边,层与包含点之间建边,点与相邻层之间建边;练习一下优先队列dijkstra和邻接表;
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define INF 0x3f3f3f3f int pp[500010],vv[500010],dist[500010]; int vis[500010],cnt,n,m,c; int lay[500010]; struct Node { int u,v,w; int next; }edge[500010];//邻接表 struct node { int pos,dd; bool operator <(const node&xx)const { return dd>xx.dd; } }cur,now; void addedge(int u,int v,int w)//邻接表 { cnt++; edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=pp[u]; pp[u]=cnt; } priority_queue<node> q; void dijkstra() { int i,j,k,u,v,w; memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); dist[1]=0; cur.pos=1;cur.dd=0; q.push(cur); while(!q.empty()) { now=q.top(); q.pop(); u=now.pos; if(vis[u]) continue; vis[u]=1; for(i=pp[u];i;i=edge[i].next) { v=edge[i].v; w=edge[i].w; if(!vis[v]&&dist[v]>dist[u]+w) { dist[v]=dist[u]+w; cur.pos=v;cur.dd=dist[v]; q.push(cur); } } } } int main() { int i,j,k,u,v,w,t,temp; scanf("%d",&t); for(k=1;k<=t;k++) { scanf("%d%d%d",&n,&m,&c); memset(pp,0,sizeof(pp)); memset(vv,0,sizeof(vv)); memset(dist,INF,sizeof(dist)); cnt=0; for(i=1;i<=n;i++) { scanf("%d",&u); lay[i]=u; vv[u]=1; } for(i=1;i<n;i++) { if(vv[i]&&vv[i+1])//相邻层之间建边 { addedge(n+i,n+i+1,c);//使用n个点以外的编号 addedge(n+i+1,n+i,c); } } for(i=1;i<=n;i++) { addedge(lay[i]+n,i,0);//层与所包含点建边 if(lay[i]>1) addedge(i,lay[i]+n-1,c);//点与相邻层建边 if(lay[i]<n) addedge(i,lay[i]+n+1,c);//点与相邻层建边 } for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w);//点与点之间建边 addedge(u,v,w); addedge(v,u,w); } dijkstra(); temp=dist[n]; printf("Case #%d: ",k); if(temp==INF) printf("-1\n"); else printf("%d\n",temp); } return 0; }
有些梦想现在不去实现,以后就再也没机会了!!