日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

链式前向星模板 建图+dfs+bfs+dijkstra

發(fā)布時(shí)間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 链式前向星模板 建图+dfs+bfs+dijkstra 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

邊沒(méi)有用struct封裝起來(lái),節(jié)點(diǎn)和邊的計(jì)數(shù)起點(diǎn)如果不符合習(xí)慣可以稍作修改

建圖+DFS+BFS

#include <cstdio> #include <cstring> #include <iostream>using namespace std; typedef long long LL; const int inf = 0x3f3f3f3f; const int maxn = 1005; int n, m, all = -1; // n:點(diǎn)數(shù) m:邊數(shù) all:邊的編號(hào) (邊的編號(hào)由0開(kāi)始,點(diǎn)的編號(hào)從1開(kāi)始) int pre[maxn]; // pre[e] e這條邊同一出發(fā)點(diǎn)的上一條出邊 int last[maxn]; // last[v] 以v為起點(diǎn)構(gòu)建的最后一條邊 int to[maxn]; // to[e] e連向的點(diǎn) int que[maxn]; // 數(shù)組模仿隊(duì)列,用于存bfs順序,que 從1開(kāi)始計(jì)數(shù),詳見(jiàn)bfs函數(shù) bool vis[maxn]; // vis[v] v是否被訪問(wèn)過(guò)void Build(int x, int y, int w = 1) // 建立x->y的邊,權(quán)默認(rèn)1 {pre[++all] = last[x];last[x] = all;to[all] = y;cost[all] = w; }void input() {all = -1;memset(last, -1, sizeof(last));cin >> n >> m; // n點(diǎn) m邊f(xié)or (int i = 1; i <= m; i++){int a,b,w;cin >> a >> b; // 帶權(quán)則加上 >> wBuild(a, b);Build(b, a); // 無(wú)向圖} }void dfs(int u) // 調(diào)用前需要初始化vis {int ed = last[u], dst; // ed表示邊(edge),dst表示ed連向的點(diǎn)vis[u] = true;cout << u << endl; // dfs的操作,這里是打印while (ed != -1){dst = to[ed];if (!vis[dst]) dfs(dst);ed = pre[ed]; // 遍歷上一條邊} }void bfs(int u) // 邏輯復(fù)雜,需要花時(shí)間理解 {memset(vis, 0, sizeof(vis));int head = 1, tail = 1, now, ed, dst; // head,tail表示頭尾指針,now表示當(dāng)前節(jié)點(diǎn)que[head] = u;vis[u] = true;while (head <= tail){now = que[head];ed = last[now];while (ed != -1) // 遍歷now的所有出度{dst = to[ed];if (!vis[dst]) {vis[dst] = true;que[++tail] = dst; }ed = pre[ed];}head++;}for (int i = 1; i <= n; i++) cout << que[i] << endl; // 打印 }int main() {input();memset(vis, 0, sizeof(vis));dfs(1);cout << endl;bfs(1);return 0; }

輸入,在書(shū)上隨便找了一張無(wú)向圖

結(jié)果

誰(shuí)能告訴我鏈?zhǔn)角跋蛐堑挠⑽拿巧?orz

Dijkstra
模板是一樣的,在輸入的時(shí)候做了些改動(dòng),加入了權(quán)值

#include <cstdio> #include <cstring> #include <iostream>using namespace std; typedef long long LL; const int inf = 0x3f3f3f3f; const int maxn = 1005; int n, m, all = -1; // n:點(diǎn)數(shù) m:邊數(shù) all:邊的編號(hào) (邊的編號(hào)由0開(kāi)始,點(diǎn)的編號(hào)從1開(kāi)始) int pre[maxn]; // pre[e] e這條邊同一出發(fā)點(diǎn)的上一條出邊 int last[maxn]; // last[v] 以v為起點(diǎn)構(gòu)建的最后一條邊 int to[maxn]; // to[e] e連向的點(diǎn) int dis[maxn]; // dis[v] v到根的距離(邊數(shù)),根到自己的距離為0,該數(shù)組用于bfs int que[maxn]; // 數(shù)組模仿隊(duì)列,用于存bfs順序,que 從1開(kāi)始計(jì)數(shù),詳見(jiàn)bfs函數(shù) bool vis[maxn]; // vis[v] v是否被訪問(wèn)過(guò) int cost[maxn]; // cost[e] e的權(quán),用于最短路算法 void Build(int x, int y, int w = 1) // 建立x->y的邊,權(quán)默認(rèn)1 {pre[++all] = last[x];last[x] = all;to[all] = y;cost[all] = w; }void input() {all = -1;memset(last, -1, sizeof(last));cin >> n >> m; // n點(diǎn) m邊f(xié)or (int i = 1; i <= m; i++){int a,b,w;cin >> a >> b >> w;Build(a, b, w);Build(b, a, w); // 無(wú)向圖} }void dijkstra(int s) // 源點(diǎn)s到所有其他點(diǎn)的最小距離,調(diào)用前應(yīng)初始化vis為0 {for(int i = 1; i <= n; i++){if(i == s) dis[i] = 0;else dis[i] = inf;}int now = s; // 當(dāng)前節(jié)點(diǎn)初始化為源點(diǎn)for(int i = 1; i <= n; i++) {vis[now] = 1;int ed = last[now]; // 取當(dāng)前節(jié)點(diǎn)的最后一條邊//printf("debug:now=%d ed=%d cost[ed]=%d\n", now, ed, cost[ed]);//debugint dst;while(ed != -1){dst = to[ed]; // ed連向的節(jié)點(diǎn)if(!vis[dst]) dis[dst] = min(dis[dst], dis[now] + cost[ed]); // 松弛:更新s到dst的距離為“直通”和“當(dāng)前距離+ed權(quán)值”的較小值ed = pre[ed];//printf("dst=%d dis[dst]=%d\n", dst, dis[dst]);//debug}int Min = inf; int pos = 0;for(int i = 1; i <= n; i++) // 找出所有節(jié)點(diǎn)中,離根最近的那個(gè)節(jié)點(diǎn)的編號(hào)記為pos{if(!vis[i]) {//printf("vis[%d]=%d\n", i, vis[i]);//debugif(dis[i] < Min) {Min = dis[i];pos = i;}}}//printf("pos=%d\n", pos);//debugnow = pos;}for (int i = 1; i <= n; i++) // print{if (i == s) continue;cout << s << " -> " << i << " = " << dis[i] << endl;} }int main() {input();memset(vis, 0, sizeof(vis));dijkstra(2);return 0; }


輸入數(shù)據(jù)

7 10 1 2 2 1 3 5 2 3 4 2 4 6 3 4 2 2 5 10 4 6 1 5 6 3 5 7 5 6 7 9

輸出

2 -> 1 = 2 2 -> 3 = 4 2 -> 4 = 6 2 -> 5 = 10 2 -> 6 = 7 2 -> 7 = 15

總結(jié)

以上是生活随笔為你收集整理的链式前向星模板 建图+dfs+bfs+dijkstra的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。