有兩種比較簡單實現次短路的思想
題目:poj - 3255
方式一:
tips:其中if(dis2[v] < w) continue; 這句 為true的時候,說明當前節點v 的次短路已經被更新過了 , 如果w比次短路大,說明它肯定是 >= 第三短路 , 也就不用更新了。
#include #include #include #include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const int inf = 1e9 + 7;
int n , m;
int dis1[maxn] , dis2[maxn];
struct node
};vector g[maxn];
void dijkstra());
node q;
int v , w;
while(!que.empty()));
swap(dis1[to_v] , to_w);
}if(dis2[to_v] > to_w && dis1[to_w] < to_w));
}} }
}int main()
); g[v].push_back((node));
} dijkstra();
printf("%d\n",dis2[n]);
}}
方式二:
#include #include #include #include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const int inf = 1e9 + 7;
int n , m , cnt , ans;
int start = 1 , end = n;
int dis1[maxn] , dis2[maxn];
bool vis[maxn];
struct node
};struct edgea[maxn << 1];
vector g[maxn];
void getdis(int op));
else que.push((node));
int v , w;
node q;
while(!que.empty()));
} else if(op && dis2[to_v] > to_w));
}} }
}void dijkstra()
void findcdl()
}int main()
); g[v].push_back((node));
a[++cnt].x = u , a[cnt].y = v , a[cnt].w = w;
a[++cnt].x = v , a[cnt].y = u , a[cnt].w = w;
} dijkstra();
findcdl();
printf("%d\n",ans);
}}
第k短路其實 就是bfs + a*(a*==啟發式搜尋==優化剪枝)
首先求 從 終點 到 每個點的最短路 用 dis[ ] 陣列儲存
然後使用 a* 函式 , f[x] = h[x] + g[x]
題目:poj 2449
具體講解在**內
#include #include #include #include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const int inf = 1e9 + 7;
int n , m , k;
int start , end;
int ans;
//最短路部分
int dis[maxn];
bool vis[maxn];
struct node
};/*
* a* 啟發式搜尋函式 f[x] = h[x] + g[x]
* 變數 hx 表示搜尋到當前點 所用的代價
* 變數 gx 是估價函式 (估價函式要小於等於實際值,否則出錯)
*/struct edge
};/*
* count 記錄第幾次bfs拓展到此點
* 當 count == k 時 不再對此點繼續進行拓展(因為拓展的點必定大於 第k短路)
*/int count[maxn];
vector g[maxn] , g2[maxn];
/* * (因為是有向圖所以反向建圖)
* 求end到每個點的最短路
*/void dijkstra());
dis[end] = 0;
node q;
int v , w;
while(!que.empty()));
}} }}/*
* 第k短路演算法 = a* + bfs
*/void astar());
edge q;
int v , hx , gx;
while(!que.empty())
if(count[v] > k) continue;
int to_v , to_hx , to_gx;
for(int i = 0 ; i < g[v].size() ; i++));
} }while(!que.empty()) que.pop();
return;
}int main()
); g2[v].push_back((node));
} scanf(" %d %d %d",&start , &end , &k);
//此題要求start和end相同的時候 第一短路不是0 ,所以k++
if(start == end) k++;
dijkstra();
astar();
printf("%d\n",ans);
} return 0;
}
第K短路 嚴格第K短路
所謂k短路,就是從s到t的第k短的路,第1短就是最短路。如何求第k短呢?有一種簡單的方法是廣度優先搜尋,記錄t出佇列的次數,當t第k次出佇列時,就是第k短路了。但點數過大時,入佇列的節點過多,時間和空間複雜度都較高。a 是在搜尋中常用的優化,一種啟發式搜尋。簡單的說,它可以用公式表示為f n g n...
第K短路(A 演算法)
對於無向圖 spfa a 演算法 先用spfa求目標結點到各個結點的最短路徑 然後,取g x 為從初始結點到當前結點x的路徑長度,h x 為從x結點到目標結點的最短路徑長度,即h x 取dis x 即可,估價函式f x g x h x 對於有向圖 spfa a 演算法 顯然應將有向邊取反,然後求目標...
第k短路和A
第一次接觸a 感覺好神奇。啟發函式 f x g x h x 比如初始狀態為s,目標狀態為t g x 表示從s到達狀態x所消耗的代價 h x 表示從x到達t所估算的代價 g x 表示s x可能出現的最小代價 h x 表示x t可能出現的最小代價 g x g x h x h x 好吧,上面全是概念。當g...