• HDU-3499Flight (分层图dijkstra)


    一开始想的并查集(我一定是脑子坏掉了),晚上听学姐讲题才知道就是dijkstra两层;

    题意:有一次机会能使一条边的权值变为原来的一半,询问从s到e的最短路。

    将dis数组开成二维,第一维表示从源点到点i的路径长度,第二维表示是否使用了该次机会,并以此不断更新。

    用map将字符串转为int,剩下的就是dijkstra+优先队列;

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<queue>
    #define ll long long
    #define INF 1e18
    using namespace std;
    
    const int N = 1e5+10;
    const int M = 5e5+10;
    int tot,m,n;
    
    struct Edge
    {
        int v, cost, next;
    }edge[M];
    
    struct qnode
    {
        int loc,level;
        ll dis;
        bool operator < (const qnode &t) const {
            return dis > t. dis;
        }
        qnode(int a=0,int b=0,ll c=0){
            loc=a,level=b,dis=c;
        }
    }d[N][2];
    
    int head[M];
    bool vis[N][2];
    
    void addedge(int u, int v, ll w)
    {
        edge[tot]. v = v;
        edge[tot]. cost = w;
        edge[tot]. next = head[u];
        head[u] = tot ++;
    }
    
    void dijkstra(int st)
    {
        memset(vis, 0, sizeof(vis));
        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 <qnode> q;
        q. push(qnode(st,0,0));
        while(! q. empty()){
            qnode t = q. top();
            q. pop();
            int t1=t.loc,t2=t.level;
            if(vis[t1][t2])continue;
            vis[t1][t2]=true;
            for(int i = head[t1]; i != -1; i = edge[i]. next){
                int v = edge[i]. v;
                int cost = edge[i]. cost;
                if( d[v][t2].dis > d[t1][t2].dis + cost){
                    d[v][t2].dis = d[t1][t2].dis + cost;
                    q. push(qnode(v,t2,d[v][t2].dis));
                }
                if(t2==0&&d[v][t2+1].dis>d[t1][t2].dis+cost/2){        //分别记录每一段是半价的价格
                    d[v][t2+1].dis=d[t1][t2].dis+cost/2;
                    q.push(qnode(v,t2+1,d[v][t2+1].dis));
                }
            }
        }
    }
    
    
    int main(){
        while(scanf("%d%d", &n, &m)!=EOF){
            string a,b;
            map<string,int> cnt;
            cnt.clear();
            ll c;
            tot = 1;
            int k=1;
            memset(head, -1, sizeof(head));
            while(m --){
                cin>>a>>b>>c;
                if(!cnt[a])cnt[a]=k++;
                if(!cnt[b])cnt[b]=k++;
                addedge(cnt[a], cnt[b], c);
            }
            cin>>a>>b;
            if(!cnt[a])cnt[a]=k++;
            if(!cnt[b])cnt[b]=k++;
            if(m==0) {
                printf("-1
    ");
                continue;
            }
            dijkstra(cnt[a]);
            ll ans=min(d[cnt[b]][0].dis,d[cnt[b]][1].dis);
            if(ans==INF) printf("-1
    ");
            else printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Ant利用第三方的task
    读《NoSQL精粹》前三章有感
    opensuse12.3 桌面设置备忘录
    clojure中符号symbols 和变量vars的正确理解
    vim配置clojure开发环境备忘录
    移动端调试痛点?——送你五款前端开发利器
    SyntaxError: missing ) after argument list
    铺满屏幕的布局方法
    剖析height百分比和min-height百分比
    父元素高度设置为min-height,子元素高度设置为100%,但实际上子元素高度你知道是多少吗?(2019-10-26更新)
  • 原文地址:https://www.cnblogs.com/lilibuxiangtle/p/11347076.html
Copyright © 2020-2023  润新知