链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544
关于最短路的求法,当点的个数約小n<300的是候果断用floyd(n3方)跑,当点很多的时候则跑fifo优化的bellman-ford(n*m)或者dij(n*m,优先队列可以优化到m*lgn
1.数组dij:
#include<algorithm> #include<iostream> #include<cmath> #include<map> #include<string> #include<cstring> #include<vector> using namespace std; #define ll long long int #define maxn 200 const int inf=0x7fffff; int n,t; int d[maxn],mp[maxn][maxn],vis[maxn]; void dij() { d[1]=0; for(int i=0;i<=n;i++) { int mx,minf=inf; for(int j=1;j<=n;j++) { if(minf>d[j]&&!vis[j]) { minf=d[j]; mx=j; } } vis[mx]=1; for(int j=1;j<=n;j++) { if(d[j]>d[mx]+mp[mx][j]&&!vis[j]) { d[j]=d[mx]+mp[mx][j]; } } } if(d[n]!=inf) printf("%d\n",d[n]); else printf("-1\n"); return ; } int main() { //freopen("in.txt","r",stdin); int st,ed,v,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0) break; for(int i=0;i<200;i++) { vis[i]=0; d[i]=inf; for(int j=0;j<200;j++) { mp[i][j]=inf; } } for(int i=0;i<m;i++) { scanf("%d%d%d",&st,&ed,&v); if(mp[st][ed]>=v) { mp[st][ed]=v; mp[ed][st]=v; //cout<<mp[st][ed]<<endl; } }dij(); } }
2.优先队列优化的dij
#include<algorithm> #include<iostream> #include<cmath> #include<map> #include<string> #include<cstring> #include<vector> #include<queue> using namespace std; #define ll long long int #define maxn 10008 typedef pair<int,int>pii; const int inf=0x7fffff; struct Edge{ int from,to,dist; Edge(int u,int v,int d):from(u),to(v),dist(d){} }; int n; vector<Edge>edges; vector<int>G[maxn]; bool vis[maxn]; int d[maxn]; int p[maxn]; void init() { for(int i=0;i<n;i++) G[i].clear(); edges.clear(); } void addedge(int from,int to,int dist) { edges.push_back(Edge(from,to,dist)); int m=edges.size(); G[from].push_back(m-1); } int dijstra(int s,int ed) { priority_queue<pii,vector<pii>,greater<pii> >Q; for(int i=0;i<=n;i++) d[i]=inf; d[s]=0; memset(vis,0,sizeof(vis)); Q.push(make_pair(d[s],s)); while(!Q.empty()) { pii x = Q.top();Q.pop(); int u=x.second; if(vis[u]) continue; vis[u]=1; for(int i=0;i<G[u].size();i++) { Edge& e=edges[G[u][i]]; if(d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; Q.push(make_pair(d[e.to],e.to)); } } } printf("%d\n",d[ed]); } int main() { int m; //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF) { if(n==0) break; int u,v,c; init(); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&c); //cout<<u<<v<<c<<endl; addedge(u,v,c); addedge(v,u,c); } dijstra(1,n); } }
3.bellman-ford
include<algorithm> #include<iostream> #include<cmath> #include<map> #include<string> #include<cstring> #include<vector> #include<queue> using namespace std; #define ll long long int #define maxn 10008 typedef pair<int,int>pii; const int inf=0x7fffff; struct Edge{ int to,dist; Edge(int v,int d):to(v),dist(d){} }; int n; vector<Edge>edge[maxn]; bool vis[maxn]; int d[maxn]; int cnt[maxn]; void init() { for(int i=0;i<n;i++) edge[i].clear(); } void addedge(int from,int to,int dist) { edge[from].push_back(Edge(to,dist)); } void bell_man(int st,int ed) { queue<int>q; memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); for(int i=0;i<=n;i++) d[i]=inf; d[st]=0; vis[st]=1; q.push(st); while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int i=0;i<edge[u].size();i++) { Edge e=edge[u][i]; if(d[u]<inf&&d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; if(!vis[e.to]) { q.push(e.to); vis[e.to]=1; if(++cnt[e.to]>n) return ; } } } } printf("%d\n",d[ed]); } int main() { int m; //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF) { if(n==0) break; int u,v,c; init(); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&c); //cout<<u<<v<<c<<endl; addedge(u,v,c); addedge(v,u,c); } bell_man(1,n); } }4、floyd
#include<algorithm> #include<iostream> #include<cmath> #include<map> #include<string> #include<cstring> #include<vector> using namespace std; #define ll long long int #define maxn 200 const int inf=0x7fffff; int n; int d[maxn][maxn],mp[maxn][maxn]; void floyd() { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } } } } int main() { //freopen("in.txt","r",stdin); int st,ed,v,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0) break; for(int i=0;i<200;i++) { for(int j=0;j<200;j++) { if(i==j) d[i][j]=0; else d[i][j]=inf; } } for(int i=0;i<m;i++) { scanf("%d%d%d",&st,&ed,&v); if(d[st][ed]>=v) { d[st][ed]=v; d[ed][st]=v; //cout<<mp[st][ed]<<endl; } } floyd(); printf("%d\n",d[1][n]); } }