HDU 4725 最短路

来源:互联网 发布:道路工程预算软件 编辑:程序博客网 时间:2024/05/01 02:17

点击打开链接

题意:给定n个数,m条边,c是每一层的连接费用,n个数代表n层,每一个数字在一层中,从一层只能走到下一层或上一层的一个节点,费用为c,现在有m条边连接点,问你从1走到n的最小费用

思路:以两层为例,前边一堆的话代表第一层的每个点到第二层的所有点的费用都是c,其他边直接连即可,但是这么连肯定是超时的,所以我们可以每一层建立一个超级源点,这个源点到这层的每一个点费用都为0,而这些点可以连向相邻两层的超级源点费用为c,剩下的边正常连跑最短路即可

#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=200010;struct edge{    int to,cost;    edge(int a,int b){to=a;cost=b;}};typedef pair<int,int>P;vector<edge>G[maxn];int dis[maxn];void dijkstra(int s){    priority_queue<P,vector<P>,greater<P> >que;    fill(dis,dis+maxn,inf);    dis[s]=0;que.push(P(0,s));    while(!que.empty()){        P p=que.top();que.pop();        int v=p.second;        if(dis[v]<p.first) continue;        for(unsigned int i=0;i<G[v].size();i++){            edge e=G[v][i];            if(dis[e.to]>dis[v]+e.cost){                dis[e.to]=dis[v]+e.cost;                que.push(P(dis[e.to],e.to));            }        }    }}int id[maxn];bool vis[maxn];int main(){    int T,n,m,k,u,v,c,cas=1,val;    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&n,&m,&k);        for(int i=0;i<maxn;i++) G[i].clear(),vis[i]=0;        for(int i=1;i<=n;i++){            scanf("%d",&val);            id[i]=val;vis[val]=1;        }        for(int i=1;i<=n;i++){            if(id[i]==1){                G[id[i]].push_back(edge(i+n,0));                if(vis[id[i]+1]==1&&id[i]<n) G[i+n].push_back(edge(id[i]+1,k));            }else if(id[i]==n){                G[id[i]].push_back(edge(i+n,0));                if(vis[id[i]-1]==1&&id[i]>1) G[i+n].push_back(edge(id[i]-1,k));            }else{                G[id[i]].push_back(edge(i+n,0));                if(vis[id[i]+1]==1) G[i+n].push_back(edge(id[i]+1,k));                if(vis[id[i]-1]==1) G[i+n].push_back(edge(id[i]-1,k));            }        }        for(int i=0;i<m;i++){            scanf("%d%d%d",&u,&v,&c);            G[u+n].push_back(edge(v+n,c));            G[v+n].push_back(edge(u+n,c));        }        dijkstra(n+1);        if(dis[2*n]==inf) printf("Case #%d: -1\n",cas++);        else printf("Case #%d: %d\n",cas++,dis[2*n]);    }    return 0;}

0 0
原创粉丝点击