图论,最短路,堆优化迪杰斯特拉,SPFA
学习了迪杰斯特拉.
类似贪心.
也有点像弗洛伊德.
上代码.
这种是规定了起始节点为1的.
1 #include <cstdio> 2 #include <iostream> 3 #include <string> 4 #include <bits/stdc++.h> 5 6 using namespace std; 7 #define MAXN 10001 8 #define MAXM 100001 9 10 //n点m边 11 12 struct edge{ 13 int v; 14 int w; 15 int nxt; 16 }e[MAXM]; 17 int head[MAXN]; 18 int cnt; 19 20 void addedge(int x,int y,int z) { 21 e[++cnt].v=y; 22 e[cnt].w=z;//边权 23 e[cnt].nxt=head[x]; 24 head[x]=cnt; 25 } 26 int dist[MAXN]; 27 bool vis[MAXN]; 28 priority_queue< pair<int,int> > q; 29 //第一维是dist相反数,这是大根堆 30 //第二维是节点编号 31 int n,m; 32 33 34 void dijkstra () { 35 memset(dist,0x3f,sizeof(dist)); 36 memset(vis,0,sizeof(vis)); 37 dist[1]=0; 38 q.push(make_pair(0,1)); 39 while (q.size()) { 40 int x=q.top().second; 41 q.pop(); 42 if (vis[x]) continue; 43 vis[x]=1; 44 for (int i=head[x];i;i=e[i].nxt) { 45 int y=e[i].v; 46 int z=e[i].w; 47 if (dist[y]>dist[x]+z) { 48 dist[y]=dist[x]+z; 49 q.push(make_pair(-dist[y],y)); 50 } 51 } 52 } 53 } 54 55 int main () { 56 cin>>n>>m; 57 for (int i=1;i<=m;i++) { 58 int x,y,z; 59 cin>>x>>y>>z; 60 addedge(x,y,z); 61 //addedge(y,x,z); 62 } 63 dijkstra(); 64 for (int i=1;i<=n;i++) { 65 cout<<dist[i]<<" "; 66 } 67 return 0; 68 } 69 70 /* 71 5 8 72 1 2 2 73 1 3 1 74 1 5 4 75 2 3 6 76 2 4 3 77 2 5 4 78 4 5 5 79 3 5 2 80 */
其实迪杰斯特拉还可以是有起点的,
自己可以定起点,
下面就是,
这就是单元最短路,
1 #include <cstdio> 2 #include <iostream> 3 #include <string> 4 #include <bits/stdc++.h> 5 6 using namespace std; 7 #define MAXN 10001 8 #define MAXM 100001 9 10 //n点m边 11 12 struct edge { 13 int v; 14 int w; 15 int nxt; 16 } e[MAXM]; 17 int head[MAXN]; 18 int cnt; 19 20 void addedge(int x,int y,int z) { 21 e[++cnt].v=y; 22 e[cnt].w=z;//边权 23 e[cnt].nxt=head[x]; 24 head[x]=cnt; 25 } 26 int dist[MAXN]; 27 bool vis[MAXN]; 28 priority_queue< pair<int,int> > q; 29 //第一维是dist相反数,这是大根堆 30 //第二维是节点编号 31 int n,m; 32 33 34 void dijkstra (int st) { 35 memset(dist,0x3f,sizeof(dist)); 36 memset(vis,0,sizeof(vis)); 37 dist[st]=0; 38 q.push(make_pair(0,st)); 39 while (q.size()) { 40 int x=q.top().second; 41 q.pop(); 42 if (vis[x]) continue; 43 vis[x]=1; 44 for (int i=head[x]; i; i=e[i].nxt) { 45 int y=e[i].v; 46 int z=e[i].w; 47 if (dist[y]>dist[x]+z) { 48 dist[y]=dist[x]+z; 49 q.push(make_pair(-dist[y],y)); 50 } 51 } 52 } 53 } 54 55 int main () { 56 cin>>n>>m; 57 for (int i=1; i<=m; i++) { 58 int x,y,z; 59 cin>>x>>y>>z; 60 addedge(x,y,z); 61 //addedge(y,x,z); 62 } 63 for (int i=1; i<=n; i++) { 64 dijkstra(i); 65 cout<<"以"<<i<<"为起点"<<endl; 66 for (int i=1; i<=n; i++) { 67 cout<<dist[i]<<" "; 68 } 69 cout<<endl; 70 cout<<endl; 71 } 72 73 74 return 0; 75 } 76 77 /* 78 5 8 79 1 2 2 80 1 3 1 81 1 5 4 82 2 3 6 83 2 4 3 84 2 5 4 85 4 5 5 86 3 5 2 87 */
下面还有SPFA,
稀疏图上效率很高,
这是以1为起点的,
#include <cstdio> #include <iostream> #include <string> #include <bits/stdc++.h> using namespace std; #define MAXN 10001 #define MAXM 100001 //n点m边 struct edge{ int v; int w; int nxt; }e[MAXM]; int head[MAXN]; int cnt; void addedge(int x,int y,int z) { e[++cnt].v=y; e[cnt].w=z;//边权 e[cnt].nxt=head[x]; head[x]=cnt; } int dist[MAXN]; bool vis[MAXN]; queue <int> q; int n,m; void spfa () { memset(dist,0x3f,sizeof(dist)); memset(vis,0,sizeof(vis)); dist[1]=0; vis[1]=1; q.push(1); while (q.size()) { int x=q.front(); q.pop(); vis[x]=0; for (int i=head[x];i;i=e[i].nxt) { int y=e[i].v; int z=e[i].w; if (dist[y]>dist[x]+z) { dist[y]=dist[x]+z; if (!vis[y]) { q.push(y); vis[y]=1; } } } } } int main () { cin>>n>>m; for (int i=1;i<=m;i++) { int x,y,z; cin>>x>>y>>z; addedge(x,y,z); //addedge(y,x,z); } spfa(); for (int i=1;i<=n;i++) { cout<<dist[i]<<" "; } return 0; } /* 5 8 1 2 2 1 3 1 1 5 4 2 3 6 2 4 3 2 5 4 4 5 5 3 5 2 */
再看看以任意节点为起点的,
这下就全了
#include <cstdio> #include <iostream> #include <string> #include <bits/stdc++.h> using namespace std; #define MAXN 10001 #define MAXM 100001 //n点m边 struct edge { int v; int w; int nxt; } e[MAXM]; int head[MAXN]; int cnt; void addedge(int x,int y,int z) { e[++cnt].v=y; e[cnt].w=z;//边权 e[cnt].nxt=head[x]; head[x]=cnt; } int dist[MAXN]; bool vis[MAXN]; queue <int> q; int n,m; void spfa (int st) { memset(dist,0x3f,sizeof(dist)); memset(vis,0,sizeof(vis)); dist[st]=0; vis[st]=1; q.push(st); while (q.size()) { int x=q.front(); q.pop(); vis[x]=0; for (int i=head[x]; i; i=e[i].nxt) { int y=e[i].v; int z=e[i].w; if (dist[y]>dist[x]+z) { dist[y]=dist[x]+z; if (!vis[y]) { q.push(y); vis[y]=1; } } } } } int main () { cin>>n>>m; for (int i=1; i<=m; i++) { int x,y,z; cin>>x>>y>>z; addedge(x,y,z); //addedge(y,x,z); } for (int i=1; i<=n; i++) { spfa(i); cout<<"以"<<i<<"为起点"<<endl; for (int i=1; i<=n; i++) { cout<<dist[i]<<" "; } cout<<endl; cout<<endl; } return 0; } /* 5 8 1 2 2 1 3 1 1 5 4 2 3 6 2 4 3 2 5 4 4 5 5 3 5 2 */