SDUT 2143 圖結構練習——最短路徑
阿新 • • 發佈:2019-01-29
//Flyod #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int Edge[10010][10010]; int main() { int n, m; while(cin >> n >> m, n&&m) { for(int i = 1; i<=n; i++) { for(int j = 1; j <= n; j++) { (i == j) ? Edge[i][j] = 0 : Edge[i][j] = INF; } } while(m--) { int u, v, w; cin >> u >> v >> w; if(Edge[u][v] > w) Edge[u][v] = Edge[v][u] = w; } for(int k = 1; k <= n; k++) { for(int i = 1; i <= n; i++) { if(Edge[i][k] != INF) { for(int j = 1; j <= n; j++) { Edge[i][j] = min(Edge[i][k]+Edge[k][j], Edge[i][j]); } } } } cout << Edge[1][n] << endl; } return 0; } //Dijkstra #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int Edge[110][110]; int path[110];//路徑記錄(需要時記錄) int dis[110]; bool vis[110]; int n, m; void Dijkstra(int st); int main() { while(cin >> n >> m) { memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { (i == j) ? Edge[i][j] = 0 : Edge[i][j] = INF; } } int u, v, w; while(m --) { cin >> u >> v >> w; if(Edge[u][v] > w) { Edge[u][v] = Edge[v][u] = w; } } Dijkstra(1); } return 0; } void Dijkstra(int st) { for(int i = 1; i <= n; i++) { dis[i] = Edge[st][i];//源點到每個頂點的最短路徑的長度 if(i != st && dis[i] < INF) { path[i] = st; } else { path[i] = -1; } } vis[st] = 1, dis[st] = 0; for(int i = 1; i < n; i++)//從頂點st確定n-1條最短路徑 { int tmp = INF, pos; for(int j = 1; j <= n; j++) { if(!vis[j] && dis[j] < tmp)//選擇具有最短路徑的頂點pos { tmp = dis[pos = j]; } } vis[pos] = 1; for(int k = 1; k <= n; k++)//修改剩下未訪問頂點的dis { if(!vis[k] && Edge[pos][k] < INF && dis[pos]+Edge[pos][k] < dis[k]) { dis[k] = min(dis[k], Edge[pos][k]+dis[pos]); path[k] = pos; } } } cout << dis[n] << endl; } //Bellman-Ford #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int n, m; //int path[110]; int Edge[110][110]; int dis[110]; void Bellman_Ford(int st); int main() { while(cin >> n >> m) { memset(Edge, INF, sizeof(Edge)); while(m --) { int u, v, w; cin >> u >> v >> w; if(Edge[u][v] > w) { Edge[u][v] = Edge[v][u] = w; } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i == j) { Edge[i][j] = 0; } else if(Edge[i][j] == 0) { Edge[i][j] = INF; } } } Bellman_Ford(1); } return 0; } void Bellman_Ford(int st) { for(int i = 1; i <= n; i++) { dis[i] = Edge[st][i];//初始化經過一條邊的dis[u]的值就是Edge[st][u] } for(int k = 2; k <= n-1; k++)//經過k條邊到達點u,修改dis(1)[u]遞迴出dis(2)[u],....dis(n-1)[u] {//dis(1)[u]表示經過1邊到u的最短距離,...dis(n-1)[u]表示經過n-1條邊到u的最短距離 //假設a -> c 被 a -> b -> c路徑dis更新後,也許會出現d使得a -> b -> d -> c的距離dis更短 for(int u = 1; u <= n; u++)//修改每個頂點的dis[u] { if(u != st) { for(int j = 1; j <= n; j++)//考慮其他頂點 { if(Edge[j][u] < INF && dis[j] + Edge[j][u] < dis[u])//頂點j到頂點u有直接路徑,且途徑頂點j可以是的dis[u]縮短 { dis[u] = dis[j] + Edge[j][u]; } } } } } cout << dis[n] << endl; } //Bellman-Ford優化 #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; struct edge { int u, v, w; }Edge[101000]; int n, m; int dis[1010]; void Bellman_Ford(int st); int main() { while(cin >> n >> m) { memset(Edge, INF, sizeof(Edge)); for(int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; Edge[i].u = u, Edge[i].v = v , Edge[i].w = w; Edge[i+m].u = v, Edge[i+m].v = u , Edge[i+m].w = w;//無向圖 } Bellman_Ford(1); } return 0; } void Bellman_Ford(int st) { for(int i = 1; i <= n; i++) { dis[i] = INF; } dis[st] = 0; for(int k = 2; k <= n; k++) { for(int i = 1; i <= 2*m; i++) { if(dis[Edge[i].u] != INF && dis[Edge[i].u] + Edge[i].w < dis[Edge[i].v]) dis[Edge[i].v] = dis[Edge[i].u] + Edge[i].w; } } cout << dis[n] << endl; } //SPFA #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int Edge[110][110]; int n, m; int flag, ans; queue<int > Q; bool vis[110]; int dis[110]; void SPFA(int st); int main() { int u, v, w; while(~scanf("%d %d", &n, &m)) { memset(Edge, INF, sizeof(Edge)); while(m --) { scanf("%d %d %d", &u, &v, &w); if(Edge[u][v] > w) { Edge[u][v] = Edge[v][u] = w; } } SPFA(1); } return 0; } void SPFA(int st) { int tmp; memset(dis, INF, sizeof(dis)); memset(vis, 0, sizeof(vis)); vis[st] = 1, dis[st] = 0; Q.push(st); while(!Q.empty()) { tmp = Q.front(); Q.pop(); vis[tmp] = 0; for(int i = 1; i <= n; i++) { if(Edge[tmp][i] < INF && dis[tmp] + Edge[tmp][i] < dis[i]) { dis[i] = dis[tmp] + Edge[tmp][i]; if(!vis[i]) { vis[i] = 1; Q.push(i); } } } } printf("%d\n", dis[n]); }