HDU 6386 - Age of Moyu [2018杭电多校联赛第七场 A](最短路变形)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6386

【题意】
给定一个n个结点m条边的无向图,结点编号为1~n,每条边有一个类型属性,现在要从结点1出发走到结点n,连续地走同种类型的边只会花费1的代价,如果当前边的类型为A,下一步走到了类型为B的边上,就会产生额外的代价,问你最小代价是多少

【输入格式】
多组输入,每组数据的第一行为两个整数n,m(n<=1e5,m<=2e5)接下来m行每行三个整数u,v,c代表结点u,v之间有一条类型为c的无向边(1<=u,v<=n, 1<=c<=1e6)

【输出格式】
对每组数据,输出最小代价,如果无法到达终点则输出-1

【思路】
依然是最短路径,在堆结点中额外增加一项就是到达该点时所走的上一条边的类型,这样如果下一条边的类型和它一样那么可以直接更新最短路,否则要将距离加1之后再更新最短路。还有就是第一次访问到某个点是更新出来的距离不一定就是最短的,所以要让结点重复进队列,直到无法更新最短路为止.

#include<bits/stdc++.h>
using namespace std;

const int inf = 2e9;
const int maxn = 100050;

struct Edge {
    int from, to, dist;
    Edge(int f, int t, int d) :from(f), to(t), dist(d) {}
};

struct HeapNode {
    int d, u, cur;
    HeapNode(int dd, int uu,int cc) :d(dd), u(uu), cur(cc) {}
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m;           
    vector<Edge> edges; 
    vector<int> g[maxn];
    int d[maxn];              

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; ++i) g[i].clear();   
        edges.clear();  
    }

    void add(int from, int to, int dist) {  
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        g[from].push_back(m - 1);
    }

    void dijkstra(int s) {  
        priority_queue<HeapNode> que;
        for (int i = 0; i < n; ++i) d[i] = inf;
        d[s] = 0;
        que.push(HeapNode(0, s, -1));
        while (!que.empty()) {
            HeapNode x = que.top();
            que.pop();
            int u = x.u;
            int cur = x.cur;
            for (int i = 0; i < g[u].size(); ++i) {
                Edge& e = edges[g[u][i]];
                if(e.dist==cur){
                    if(d[e.to]>d[u]){
                        d[e.to]=d[u];
                        que.push(HeapNode(d[e.to],e.to,cur));
                    }
                }
                else{
                    if(d[e.to]>d[u]+1){
                        d[e.to]=d[u]+1;
                        que.push(HeapNode(d[e.to]+1,e.to,e.dist));
                    }
                }
            }
        }
    }
};

int n, m;
Dijkstra dij;

int main() {
    while(scanf("%d%d",&n,&m)==2){
        dij.init(n);
        for(int i=0;i<m;++i){
            int u,v,c;
            scanf("%d%d%d",&u,&v,&c);
            --u,--v;
            dij.add(u,v,c);
            dij.add(v,u,c);
        }
        dij.dijkstra(0);
        int ans=dij.d[n-1];
        if(ans==inf) puts("-1");
        else printf("%d\n",ans);
    }
    return 0;
}
posted @ 2018-08-14 14:46  不想吃WA的咸鱼  阅读(107)  评论(0编辑  收藏  举报