zoukankan      html  css  js  c++  java
  • 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
    ");continue;}
            dij(mpa[st]);
            ll ans=min(d[mpa[ed]][0].dis,d[mpa[ed]][1].dis);
            ans==INF?printf("-1
    "):printf("%lld
    ",ans);
        }
        return 0;
    }

    2018-09-24

  • 相关阅读:
    C++第11课 迭代器与仿函数 (二)
    C++第11课 迭代器与仿函数 (一)
    Python语法的应用
    Python面试
    02_Python之基础编程
    01_Python之_学前准备
    Sorting It All Out (拓扑排序) poj1094
    Codeforces Global Round 13 Editorial补题
    今天做题做到了并查集相关的内容~简单介绍一下关于并查集的东西
    留言板
  • 原文地址:https://www.cnblogs.com/00isok/p/9697000.html
Copyright © 2011-2022 走看看