洛谷P4568 [JLOI2011]飛行路線(分層圖最短路)
阿新 • • 發佈:2018-12-18
題目描述
和現在要乘飛機旅行,他們選擇了一家相對便宜的航空公司。該航空公司一共在個城市設有業務,設這些城市分別標記為到,一共有種航線,每種航線連線兩個城市,並且航線有一定的價格。
和現在要從一個城市沿著航線到達另一個城市,途中可以進行轉機。航空公司對他們這次旅行也推出優惠,他們可以免費在最多種航線上搭乘飛機。那麼和這次出行最少花費多少?
輸入輸出格式
輸入格式: 資料的第一行有三個整數,,分別表示城市數,航線數和免費乘坐次數。 第二行有兩個整數,,分別表示他們出行的起點城市編號和終點城市編號。 接下來有m行,每行三個整數,,表示存在一種航線,能從城市到達城市,或從城市到達城市,價格為。
輸出格式:
只有一行,包含一個整數,為最少花費。
輸入樣例#1:
5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
輸出樣例#1:
8
關於分層圖最短路
(以下來自度娘) 分層圖最短路是指在可以進行分層圖的圖上解決最短路問題。
一般模型是:
在圖上,有k次機會可以直接通過一條邊(也就是免費),問起點與終點之間的最短路徑。
一般解決這種問題的時候,我們要將最短路的 陣列開成兩維。 表示我走到了號點,使用了次機會的最短路徑是多少。
如何更新?
陣列可以由兩個方式更新,對應著兩種操作——在這個點我用不用一次機會。 我們設邊 如果用這次機會 如果不用這次機會 這些操作我們完全可以在SPFA或Dijkstra更新最短路時實現。
還要注意一個坑點 這個題的編號是從 開始的,如果不習慣的話輸入時要把編號加上。
code
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10005, maxm = 100005;
struct node
{
int f, t, v;
}e[maxm];
int n, m, tot, k, S, T, ans = 1e9;
int head[maxn], nxt[maxm], used[maxn] , dis[maxn][12];
#define ri register int
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
return x * f;
}
inline void buildnode(int a, int b, int c)
{
tot++;
e[tot].f = a;
e[tot].t = b;
e[tot].v = c;
nxt[tot] = head[a];
head[a] = tot;
}
typedef pair<int, int>p;
struct cmp
{
bool operator()(p a, p b)
{
return a.first > b.first;
}
};
priority_queue<p, vector<p>, cmp>q;
inline void dijkstra(int s)
{
for (ri i = 1; i <= n; i++)
for (ri j = 0; j <= 10; j++) dis[i][j] = 1e9;
dis[s][0] = 0;
q.push(p(dis[s][0], s));
while (!q.empty())
{
p x = q.top();
q.pop();
int flag = 0;
for (ri i = head[x.second]; i; i = nxt[i])
{
int u = e[i].t;
for(ri j = 0 ; j <= k ; j ++)
if (dis[u][j] > dis[x.second][j] + e[i].v)
{
dis[u][j] = dis[x.second][j] + e[i].v;
q.push(p(dis[u][j], u));
flag = 1;
}
for (ri j = 1; j <= k; j++)
{
if (dis[u][j] > dis[x.second][j - 1])
dis[u][j] = dis[x.second][j - 1], flag = 1;
}
if (flag == 1) q.push(p(dis[u][0], u));
}
}
}
int main()
{
n = read(); m = read(); k = read();
S = read(); T = read();
S += 1; T += 1;
for (ri i = 1; i <= m; i++)
{
int a, b, c;
a = read(); b = read(); c = read();
a += 1, b += 1;
buildnode(a, b, c);
buildnode(b, a, c);
}
dijkstra(S);
for (ri i = 0; i <= k; i++) ans = min(ans, dis[T][i]);
printf("%d", ans);
//system("pause");
}
End