最短路模板
//dijkstra算法求单源点最短路:类似求最小生成树的prim算法。要求边权值非负。 #include<iostream> #include<cstring> using namespace std; const int MAX=10000007; int mp[1005][1005],dis[1005],vis[1005]; int n,m; void dijk(int s)//求s到每个点的最短路 { for(int i=1;i<=n;i++) //初始化s到每个点的距离 { dis[i]=mp[s][i]; vis[i]=0; } vis[s]=1; for(int i=1;i<=n;i++)//n次循环 { int Min=MAX,sta=0; for(int j=1;j<=n;j++) { if(!vis[j]&&dis[j]<Min) { Min=dis[j]; sta=j; } } if(sta==0) continue; vis[sta]=1; for(int j=1;j<=n;j++)//松弛 { if(!vis[j]&&mp[sta][j]!=MAX&&dis[j]>dis[sta]+mp[sta][j]) dis[j]=dis[sta]+mp[sta][j]; } } } int main() { return 0; } ************************************************************************** //floyd算法求每两个点之间的最短路。三重循环。要求边权值非负 for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(mp[i][j]>mp[i][k]+mp[k][j]){ mp[i][j]=mp[i][k]+mp[k][j]; } } } } *************************************************************************** //spfa算法适用于边权值为正和负的两种情况。victor写的。容易爆内存。 /* 1.队列Q={s} 2.取出队头u,枚举所有的u的临边 .若d(v)>d(u)+w(u,v)则改进 ,pre(v)=u,由于d(v) 减少了,v可能在以后改进其他的点,所以若v不在Q中,则将v入队。 3.一直迭代2,直到队列Q为空(正常结束),或有的点的入队次数>=n(含有负圈)(加一个cnt数组 记录每个点的入队次数)。 */ #include<iostream> #include<cstring> #include<queue> #include<vector> using namespace std; const int inf=9999999; int vis[10004],dis[10004],n; struct node{ int from,to,value; }; vector<node>g[10004]; void spfa(int s) { for(int i=0;i<=n;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); vis[s]=1; dis[s]=0; queue<int>q; q.push(s); while(!q.empty()){ int cur=q.front(); q.pop(); for(int i=0;i<(int)g[cur].size();i++){ int k=g[cur][i].to; if(dis[k]>dis[cur]+g[cur][i].value){ dis[k]=dis[cur]+g[cur][i].value; if(!vis[k]){ vis[k]=1; q.push(k); } } } vis[cur]=0; } } int main() { return 0; } /***************************************************************/ //spfa 模板和上一个相比占用内存小 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn=50004,inf=0x7fffffff; struct node { int to,next,val; } edge[maxn*4];//! int mark[maxn],head[maxn],tot,dis[maxn],n,m; void add(int a,int b,int c) { edge[tot].to=b; edge[tot].next=head[a]; edge[tot].val=c; head[a]=tot++; } void spfa(int s) { for(int i=0;i<=n;i++) dis[i]=inf; memset(mark,0,sizeof(mark)); queue<int>q; dis[s]=0; mark[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); mark[u]=0; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].val) { dis[v]=dis[u]+edge[i].val; if(!mark[v]) { q.push(v); mark[v]=1; } } } } } main() { while(scanf("%d%d",&n,&m)==2){ int a,b,c; memset(head,-1,sizeof(head));//记住初始化head和tot tot=0; //边的编号从0开始 for(int i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c); //add(b,a,c);反向边 } spfa(0); printf("%d\n",dis[n-1]); } return 0; }