hdu 3499 flight 【分层图】+【Dijkstra】
<题目链接>
题目大意:
现在给你一些点,这些点之间存在一些有向边,每条边都有对应的边权,有一次机会能够使某条边的边权变为原来的1/2,求从起点到终点的最短距离。
解题分析:
分层图最短路模板题,由于最多只能将一条边变成原来的1/2,所以我们在原来二维的图形上多加一层,由第一层到第二层的边代表该边边权为原边权的1/2。就按这种思想跑一遍Dijkstra即可。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <string> #include <map> #include <iostream> using namespace std; typedef long long ll; #define INF 1e18 const int N=1e5+7; const int M=5e5+7; int n,m,cnt,head[N]; bool vis[N][2]; struct DEGE{ int to,next; ll val; }edge[M]; struct NODE{ int loc,level; ll dis; bool operator <(const NODE &tmp)const{ return dis>tmp.dis; } NODE(int a=0,int b=0,ll c=0){ loc=a,level=b,dis=c; } }d[N][2]; void init(){ cnt=0; memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); } void add(int u,int v,ll w){ edge[++cnt].to=v,edge[cnt].val=w; edge[cnt].next=head[u],head[u]=cnt; } void dij(int st){ for(int i=1;i<=n;i++){ for(int j=0;j<=1;j++) d[i][j].dis=INF; //将所有点到起点的距离置为无穷 } d[st][0].dis=0; priority_queue<NODE>q; q.push(NODE(st,0,0)); while(!q.empty()){ NODE now = q.top(); q.pop(); int tmp1=now.loc,tmp2=now.level; if(vis[tmp1][tmp2])continue; vis[tmp1][tmp2]=true; for(int i=head[tmp1];~i;i=edge[i].next){ int v=edge[i].to; ll cost =edge[i].val; if(d[v][tmp2].dis>d[tmp1][tmp2].dis+cost){ d[v][tmp2].dis=d[tmp1][tmp2].dis+cost; q.push(NODE(v,tmp2,d[v][tmp2].dis)); } if(tmp2==0&&d[v][tmp2+1].dis>d[tmp1][tmp2].dis+cost/2){ //如果tmp1---->v之间的边变成原来值的1/2 d[v][tmp2+1].dis=d[tmp1][tmp2].dis+cost/2; q.push(NODE(v,tmp2+1,d[v][tmp2+1].dis)); } } } } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ map<string,int>mpa; init(); int tot=0; string st,ed;ll w; for(int i=1;i<=m;i++){ cin>>st>>ed>>w; if(!mpa[st])mpa[st]=++tot; //如果这个字符串没有出现过,就给它编号 if(!mpa[ed])mpa[ed]=++tot; add(mpa[st],mpa[ed],w); //建立有向边 } cin>>st>>ed; if(m==0){printf("-1\n");continue;} dij(mpa[st]); ll ans=min(d[mpa[ed]][0].dis,d[mpa[ed]][1].dis); ans==INF?printf("-1\n"):printf("%lld\n",ans); } return 0; }
2018-09-24
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。