1. 程式人生 > >hdu 3499 flight 【分層圖】+【Dijkstra】

hdu 3499 flight 【分層圖】+【Dijkstra】

mil 沒有 http ++ print 所有 思想 for def

<題目鏈接>

題目大意:

現在給你一些點,這些點之間存在一些有向邊,每條邊都有對應的邊權,有一次機會能夠使某條邊的邊權變為原來的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

hdu 3499 flight 【分層圖】+【Dijkstra】