分層圖求最短路學習筆記
阿新 • • 發佈:2019-01-31
單純的最短路和網路流 大家都會
但是如果增加了點干擾物 可能就停滯在前了
例題
我們設定表示走到第號點 ,免費經過了條邊的最短路.
對於當前每條邊 我們討論使其免費和不免費兩種狀態 並更新當前最短路 壓入佇列 參與之後的更新
改造路’s
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <queue>
#define inc(i) (++ i)
#define dec(i) (-- i)
using namespace std;
const int N = 10000 + 7 , K = 20 + 2 , M = 50000 + 7;
int n , m , k , Dis[N][K];
int Head[N] , Node[M << 1] , Next[M << 1] , W[M << 1] , tot = 1;
bool inq[N][K];
struct Node_1
{
int u , k , w;
bool operator < (const Node_1& a)const
{
return w > a.w;
}
};
priority_queue <Node_1> Q;
inline void Add(int u , int v , int w)
{
Next[inc(tot)] = Head[u] , Head[u] = tot , W[tot] = w , Node[tot] = v;
Next[inc(tot)] = Head[v] , Head[v] = tot , W[tot] = w , Node[tot] = u;
}
inline void Dij(int S)
{
memset (Dis , 127 / 3 , sizeof(Dis));
Node_1 u;
u.u = S , u.k = 0;
u.w = Dis[S][0] = 0 , Q.push(u) , inq[S][0] = 1;
int v;
while(!Q.empty())
{
u = Q.top() , Q.pop() , inq[u.u][u.k] = 0;
for(int i = Head[u.u] ; i ; i = Next[i])
{
v = Node[i];
if(Dis[v][u.k] > Dis[u.u][u.k] + W[i])
{
Dis[v][u.k] = Dis[u.u][u.k] + W[i];
if(!inq[v][u.k]) Q.push(Node_1{v , u.k , Dis[v][u.k]}) , inq[v][u.k] = 1;
}
if(u.k + 1 <= k)
if(Dis[v][u.k + 1] > Dis[u.u][u.k])
{
Dis[v][u.k + 1] = Dis[u.u][u.k];
if(!inq[v][u.k + 1]) Q.push(Node_1{v , u.k + 1 , Dis[v][u.k + 1]}) , inq[v][u.k + 1] = 1;
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
for(int i = 1 , u , v , w ; i <= m ; inc(i)) cin >> u >> v >> w , Add(u , v , w);
Dij(1);
printf("%d" , Dis[n][k]);
return 0;
}
[JLOI2011]飛行路線’s
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <queue>
#define inc(i) (++ i)
#define dec(i) (-- i)
using namespace std;
const int N = 10000 + 7 , K = 20 + 2 , M = 50000 + 7;
int n , m , k , Dis[N][K] , S , E;
int Head[N] , Node[M << 1] , Next[M << 1] , W[M << 1] , tot = 1;
bool inq[N][K];
struct Node_1
{
int u , k , w;
bool operator < (const Node_1& a)const//優先佇列套上結構體判斷語句需要打const
{
return w > a.w;
}
};
priority_queue <Node_1> Q;
inline void Add(int u , int v , int w)
{
Next[inc(tot)] = Head[u] , Head[u] = tot , W[tot] = w , Node[tot] = v;
Next[inc(tot)] = Head[v] , Head[v] = tot , W[tot] = w , Node[tot] = u;
}
inline void Dij(int S)
{
memset(Dis , 127 / 3 , sizeof(Dis));
Node_1 u;
Dis[S][0] = 0 , Q.push(Node_1{S , 0 , 0}) , inq[S][0] = 1;
int v;
while(!Q.empty())
{
u = Q.top() , Q.pop() , inq[u.u][u.k] = 0;
for(int i = Head[u.u] ; i ; i = Next[i])
{
v = Node[i];
if(Dis[v][u.k] > Dis[u.u][u.k] + W[i])
{
Dis[v][u.k] = Dis[u.u][u.k] + W[i];
if(!inq[v][u.k]) Q.push(Node_1{v , u.k , Dis[v][u.k]}) , inq[v][u.k] = 1;
}
if(u.k + 1 <= k)
if(Dis[v][u.k + 1] > Dis[u.u][u.k])
{
Dis[v][u.k + 1] = Dis[u.u][u.k];
if(!inq[v][u.k + 1]) Q.push(Node_1{v , u.k + 1 , Dis[v][u.k + 1]}) , inq[v][u.k + 1] = 1;
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
cin >> S >> E;
for(int i = 1 , u , v , w ; i <= m ; inc(i)) cin >> u >> v >> w , Add(u + 1 , v + 1 , w);
Dij(S + 1);
printf("%d" , Dis[E + 1][k]);
return 0;
}