题目链接:The Shortest Path in Nya Graph
解题思路:这道题比较特殊,但是从题面很容易想到最短路,这里有10^5个点,而且在不同的层中,只有有节点的相邻两层才能互通耗费为c。那么我们就可以在每一层中虚拟出两个节点,一个是进入该层的节点和一个出去的节点。我们只需将进入的点连接该层的每一个点,在将该层的每一个点连接出去的节点。相邻的层要将出去的节点连接另一层进入的节点。那么我们对这个可以SPFA也可以再用优先队列实现的dijkstra。这里用STL会慢一点。
#include<stdio.h> #include<string.h> #include<vector> #include<queue> #define MAX 100010 #define INF 0x5fffffff using namespace std; struct A{ int x, dis; A(){} A(int a, int b){x = a, dis = b;} }; typedef struct A node; bool done[MAX * 3]; int d[MAX * 3]; vector<node> map[MAX * 3]; int n, m, c; bool operator < (node a, node b){ return a.dis > b.dis; } int numNum(int a , int b){ return a < b ? a : b; } void addedge(int x, int y, int w){ map[x].push_back(node(y, w)); } void dijkstra(){ int i, j, k; node s, tem; priority_queue<node> que; d[1] = 0; que.push(node(1, 0)); while(!que.empty()){ s = que.top(); que.pop(); int st = s.x; if(done[st]){ continue; } done[st] = true; for(i = 0; i < map[st].size(); i++){ tem = map[st][i]; if(d[tem.x] > d[st] + tem.dis){ d[tem.x] = d[st] + tem.dis; que.push(node(tem.x, d[tem.x])); } } } } int main(){ int i, j, k, t, x, y, w, tem, tot = 1; scanf("%d", &t); while(t--){ for(i = 0; i < MAX * 3; i++){ map[i].clear(); d[i] = INF; done[i] = false; } scanf("%d%d%d", &n, &m, &c); for(i = 1; i <= n; i++){ scanf("%d", &tem); addedge(n + 2 * tem - 1, i, 0); addedge(i, n + 2 * tem, 0); } for(i = 0; i < m; i++){ scanf("%d%d%d", &x, &y, &w); addedge(x, y, w); addedge(y, x, w); } for(i = 1; i < n; i++){ addedge(n + 2 * i, n + 2 * (i + 1) - 1, c); addedge(n + 2 * (i + 1), n + 2 * i - 1, c); } dijkstra(); if(d[n] == INF){ printf("Case #%d: -1\n", tot++); } else{ printf("Case #%d: %d\n", tot++, d[n]); } } return 0; }