最短路
模板。
dijkstra。邻接矩阵+函数。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 int n, m, a, b, c; 7 8 #define maxn 110 9 #define INF 10000000 10 int w[maxn][maxn]; 11 int d[maxn]; 12 bool v[maxn]; 13 //int fa[maxn];//如果需要记录路径。 14 //点从1开始 15 void ini(){ 16 for (int i = 1; i <= n; i++) 17 for (int j = 1; j <= n; j++) 18 w[i][j] = INF; 19 //如果需要记录路径 20 // for (int i = 1; i <= n; i++) 21 // fa[i] = i; 22 } 23 24 void dijkstra(int s){ 25 memset(v, false, sizeof(v)); 26 for (int i = 1; i <= n; i++) 27 d[i] = INF; 28 d[s] = 0; 29 //每次确定一个点到源点的最短路径。 30 for (int i = 0; i < n; i++){ 31 int x, m = INF; 32 //找出该点及该点最短路径 33 for (int y = 1; y <= n; y++){ 34 if(!v[y] && d[y] <= m) 35 m = d[x = y]; 36 } 37 //标记该点已找到最短路径 38 v[x] = true; 39 //用该点松弛其他点 40 for (int y = 1; y <= n; y++){ 41 d[y] = min(d[y], d[x] + w[x][y]); 42 //如果要输出路径的话。将上面一行替换成下面四行。 43 // if(d[y] > d[x] + w[x][y]){ 44 // d[y] = d[x] + w[x][y]; 45 // fa[y] = x; 46 // } 47 } 48 } 49 } 50 51 int main() 52 { 53 while(scanf("%d%d", &n,&m),n+m){ 54 ini(); 55 56 for (int i = 0; i < m; i++){ 57 scanf("%d%d%d", &a, &b, &c); 58 if(w[a][b] > c) 59 w[a][b] = w[b][a] = c; 60 } 61 62 dijkstra(1); 63 64 printf("%d\n", d[n]); 65 } 66 return 0; 67 } 68 //HDU2544无向正权图。
dijkstra。邻接表+优先队选边时优化(n->logn)。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <queue> 6 using namespace std; 7 8 int u, v, w; 9 10 #define maxn 110 11 #define INF 10000000 12 //点号从0开始,边号从0开始。 13 14 //边 15 struct Edge{ 16 int from, to, dist; 17 Edge(int u, int v, int d):from(u),to(v),dist(d){} 18 }; 19 20 //点 21 struct HeapNode{ 22 int d, u; 23 bool operator < (const HeapNode& rhs) const{ 24 return d > rhs.d; 25 } 26 }; 27 28 29 int n, m; 30 31 vector<Edge> edges; 32 vector<int> G[maxn]; 33 bool done[maxn]; 34 int d[maxn]; 35 //记录路径 36 //int p[maxn]; 37 38 void init(){ 39 for (int i = 0; i < n; i++) 40 G[i].clear(); 41 edges.clear(); 42 //初始化路径 43 // for (int i = 0; i < n; i++) 44 // p[i] = i; 45 } 46 47 void AddEdge(int from, int to, int dist){ 48 edges.push_back(Edge(from, to, dist)); 49 int cnt = edges.size(); 50 G[from].push_back(cnt-1);//边从0开始标号 51 } 52 53 void dijkstra(int s){ 54 priority_queue<HeapNode> Q; 55 for(int i = 0; i < n; i++) 56 d[i] = INF; 57 d[s] = 0; 58 memset(done, false, sizeof(done)); 59 Q.push((HeapNode){0,s}); 60 61 //直到没有新的最短路产生。 62 while(!Q.empty()){ 63 HeapNode x = Q.top(); 64 Q.pop(); 65 int u = x.u; 66 67 if(done[u]) continue;//有可能一个点多次入队,如果已经找到了该点最短路,直接continue 68 done[u] = true; 69 70 //遍历该点的每条边 71 for (int i = 0; i < G[u].size(); i++){ 72 Edge& e = edges[G[u][i]]; 73 //松弛该边上的点 74 if(d[e.to] > d[u] + e.dist){ 75 d[e.to] = d[u] + e.dist; 76 //记录路径 77 // p[e.to] = G[u][i]; 78 //入队,等待选最短路,松弛其他点。 79 Q.push((HeapNode){d[e.to], e.to}); 80 } 81 } 82 } 83 } 84 85 int main() 86 { 87 while(~scanf("%d%d", &n, &m), n+m){ 88 init(); 89 for (int i = 0; i < m; i++){ 90 scanf("%d%d%d", &u,&v,&w); 91 u--; 92 v--; 93 AddEdge(u,v,w); 94 AddEdge(v,u,w); 95 } 96 dijkstra(0); 97 printf("%d\n", d[n-1]); 98 } 99 return 0; 100 } 101 //HDU2544无向正权
spfa
1 #include <iostream> 2 #include <queue> 3 #include <vector> 4 #include <cstring> 5 #include <cstdio> 6 7 using namespace std; 8 9 #define maxn 110 10 #define INF 10000000 11 int u, v, w; 12 //点序号从0开始,边序号从0开始。 13 struct Edge{ 14 int from, to, dist; 15 Edge(int u, int v, int w):from(u),to(v),dist(w){} 16 }; 17 18 int n, m; 19 vector<Edge> edges; 20 vector<int> G[maxn]; 21 bool inq[maxn];//是否在队列中 22 int d[maxn]; 23 //int p[maxn];//记录路径 24 int cnt[maxn];//进队次数 25 26 void init(){ 27 for (int i = 0; i < n; i++) 28 G[i].clear(); 29 edges.clear(); 30 // for (int i = 0; i < n; i++)//初始化路径 31 // p[i] = i; 32 } 33 34 //无向图,调用2次加边函数。去一条回一条。 35 void AddEdge(int from, int to, int dist){ 36 edges.push_back((Edge){from, to, dist}); 37 int cont = edges.size(); 38 G[from].push_back(cont-1); 39 } 40 41 bool spfa(int s){ 42 //记录点的队列 43 queue<int> Q; 44 memset(inq, 0, sizeof(inq)); 45 memset(cnt, 0, sizeof(cnt)); 46 47 for(int i = 0; i < n; i++) 48 d[i] = INF; 49 d[s] = 0; 50 inq[s] = true; 51 Q.push(s); 52 53 while(!Q.empty()){//取出一个点,松弛该点每条边 54 int u = Q.front(); 55 Q.pop(); 56 inq[u] = false; 57 for (int i = 0; i < G[u].size(); i++){ 58 Edge& e = edges[G[u][i]]; 59 //点u可达,判断是否能松弛e.to 60 if(d[u] < INF && d[e.to] > d[u] + e.dist){ 61 d[e.to] = d[u] + e.dist; 62 // p[e.to] = G[u][i];//记录路径 63 if(!inq[e.to]){ 64 Q.push(e.to); 65 inq[e.to] = true; 66 if(++cnt[e.to] > n)//每一次入队代表被松弛了一次,一共n个点,每个点最多被松弛n-1次。 67 return false; 68 } 69 } 70 } 71 } 72 return true; 73 } 74 75 int main() 76 { 77 while(scanf("%d%d", &n, &m),n+m){ 78 init(); 79 for (int i = 0; i < m; i++){ 80 scanf("%d%d%d", &u, &v, &w); 81 u--; 82 v--; 83 AddEdge(u, v, w); 84 AddEdge(v, u, w); 85 } 86 spfa(0); 87 printf("%d\n", d[n-1]); 88 } 89 return 0; 90 }//HDU2544无向正权
floyd
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 #define maxn 110 6 #define INF 10000000 7 int d[maxn][maxn]; 8 int n, m; 9 int u, v, w; 10 11 void ini(){ 12 for (int i = 0; i < n; i++){ 13 for (int j = 0; j < n; j++){ 14 d[i][j] = INF; 15 } 16 } 17 } 18 19 void floyd(){ 20 for (int k = 0; k < n; k++) 21 for (int i = 0; i < n; i++) 22 for (int j = 0; j < n; j++) 23 d[i][j] = min(d[i][j], d[i][k]+d[k][j]); 24 } 25 26 int main() 27 { 28 while(scanf("%d%d", &n, &m),n+m){ 29 ini(); 30 for (int i = 0; i < m; i++){ 31 scanf("%d%d%d", &u, &v, &w); 32 u--; 33 v--; 34 d[u][v] = d[v][u] = w;//v到u的最短路就是边权。 35 } 36 floyd(); 37 printf("%d\n", d[0][n-1]); 38 } 39 return 0; 40 } 41 //HDU2544无向正权

浙公网安备 33010602011771号