最短路径问题,具体可以用dijkstr算法,ford算法。。还有SPFA等等。
然后各种 算法在实际问题又有区别。
SPFA在稀疏图上快,因为是通过边来增广的。 dijkstra在稠密图上快。因为是通过点来增广的。 某些情况下dijkstra 加上 堆优化 在处理大数据的时候会比SPFA快很多。 但是SPFA在随机数据的综合表现中相比dijkstra优势还是比较大的。
spfa算法模板:
#include<iostream> #include<queue> using namespace std; int cost[53][53]; int n,ans; bool visited[53]; int dist[53]; void SPFA(int Start){ int i; for(i=1;i<=52;i++) dist[i]=100000000; //初始化start点到其他点的距离为无限。 dist[Start]=0; //start到本身的距离为0 queue<int >q; q.push(Start); while(!q.empty()){ int u=q.front(); q.pop(); visited[u]=false; for(i=1;i<=52;i++) if(dist[i]>dist[u]+cost[u][i]){ dist[i]=dist[u]+cost[u][i]; if(!visited[i]){ visited[i]=true; q.push(i); } } } } int main() { int i,j; scanf("%d",&n);getchar(); for ( i=1;i<=52;i++) for ( j=1;j<=52;j++) if (i==j) cost[i][j]=0; else cost[i][j]=0xFFFFFFF; char ch1,t,ch2; int x,y,c,p; for ( i=1;i<=n;i++) { scanf("%c%c%c%d",&ch1,&t,&ch2,&c); if (ch1>='A' && ch1<='Z') x=(ch1-64); else x=(ch1-96)+26; if (ch2>='A' && ch2<='Z') y=(ch2-64); else y=(ch2-96)+26; if (cost[x][y]>c)//防止重边 { cost[x][y]=c; cost[y][x]=c; } getchar(); } for ( i=1;i<=52;i++) visited[i]=false; SPFA(26); int ans=0xFFFFFFF; for ( i=1;i<=25;i++) if (ans>dist[i]) { ans=dist[i]; p=i; } printf("%c %d\n",char(p+64),ans); return 0; }
#include <iostream> using namespace std; const int maxn=2000; int n,m; int f[maxn+1][maxn+1]; int s,t; double dist[maxn+1]; bool hash[maxn+1]; void init() { cin>>n>>m; int a,b,c; for (int i=0;i<m;i++) { cin>>a>>b>>c; f[a][b]=c; f[b][a]=c; } cin>>s>>t; } void dijkstra() { int i,j; for(i=1;i<=n;i++) { if(f[s][i]==0) //没用通过的方法 { dist[i]=100000.0; continue; } dist[i]=100.0*100/(double)(100-f[s][i]); } dist[s]=100000.0; hash[s]=true; for ( i=1;i<n;i++) //做N-1找s到剩下点的最短路径。 { double min=100000.0; int u=0; for ( j=1;j<=n;j++) //找出身下未添加的点,当中的到s的最短距离。 { if (hash[j]) continue; if (min>dist[j]) {min=dist[j];u=j;} } hash[u]=true; //标记u点添加到找到集合 for ( j=1;j<=n;j++) { if (f[u][j]==0) continue; if (dist[j]>dist[u]*100/(double)(100-f[u][j])) //如果有一个点能通过u到达j使得原来到达j的距离大于 这条路的距离,那么改变dist[j]的大小 dist[j]=dist[u]*100/(double)(100-f[u][j]); } } //cout<<dist[t]<<endl; printf("%.8lf\n",dist[t]); } int main() { init(); dijkstra(); return 0; }