自己整理的最短路模板,,对于最短路问题主要就是难在构图方面~~
//Dijstra O(n^2) //Dijkstra对于有负边权的最短路径不支持 void Dijstra() { int i,j; for(i=0; i<n; ++i) { dis[i]=INF; vis[i]=0; } dis[1]=0; int v; for(i=1; i<=n; ++i) { min=INF; for(j=1; j<=n; ++j) { if(!vis[j]&&d[j]<min) //每次找点的过程,首先这个点没有被发现,然后找一个最小点 { min=d[j]; v=j; } } vis[v]=1; for(j=1; j<=n; ++j) //加进最小点后,再修改从源点没有被发现的点的最短路径 { if(!vis[j]&&dis[v]+mp[v][j]<dis[j]) dis[j]=dis[v]+mp[v][j]; } } int ans=-1; for(i=1; i<=n; ++i) if(dis[i]>ans) ans=dis[i]; } int main() { for(int i=0; i<n; ++i) //初始化 类似prim for(int j=0; j<n; ++j) { if(i!=j) mp[i][j]=INF; else mp[i][j]=0; } while(m--) { mp[i][j]=mp[j][i]=~~; } Dijstra(); return 0; } ============================================================= //Dijstra 优先队列+邻接表 //优化后复杂度为O(mlogn) struct point { int val,id; point(int id,int val):id(id),val(val) {} bool operator <(const point &x)const { return val>x.val; } }; void dijkstra(int s) { memset(vis,0,sizeof(vis)); for(int i=0; i<n; i++) dis[i]=INF; priority_queue<point> q; q.push(point(s,0)); vis[s]=true; dis[s]=0; while(!q.empty()) { int cur=q.top().id; q.pop(); vis[cur]=true; for(int i=head[cur]; i!=-1; i=e[i].next) { int id=e[i].to; if(!vis[id] && dis[cur]+e[i].val < dis[id]) { dis[id]=dis[cur]+e[i].val; q.push(point(id,dis[id])); } } } } ============================================================= //Floyd O(n^3) void Floyd() { for(int i=0; i<n; ++i) for(int j=0; j<n; ++j) mp[i][j]=mp[j][i]=~~; for(int i=0; i<n; ++i) for(int j=0; j<n; ++j) for(int k=0; k<n; ++k) if(mp[j][k]>mp[j][i]+mp[i][k]) mp[j][k]=mp[j][i]+mp[i][k]; } ============================================================= //Spfa 邻接矩阵 O(kE)E为边数,k一般为2或3 //可以计算带负环的回路 void Spfa() { int i,j; for(int i=0; i<n; ++i) { d[i]=INF; vis[i]=0; } queue<int>q; q.push(start); d[start]=0; vis[start]=1; while(!q.empty()) { int v=q.front(); q.pop(); vis[v]=0; // 这点别忘记 for(i=0; i<n; ++i) { if(d[i]>d[v]+mp[v][i]) { d[i]=d[v]+mp[v][i]; if(!vis[i]) { q.push(i); vis[i]=1; } } } } int ans=-1; for(i=1; i<=n; ++i) if(d[i]>ans) ans=d[i]; } int main() { for(int i=0; i<n; ++i) for(int j=0; j<n; ++j) { if(i!=j) mp[i][j]=INF; else mp[i][j]=0; } while(m--) { mp[i][j]=mp[j][i]=~~; } Spfa(); return 0; } ============================================================= //Spfa 邻接表(推荐) struct node { int v; int next; int cost; } Edge,e[M]; //Insert //无向图的spfa的边要存两遍 void addEdge() { mp[cnt].v=to; mp[cnt].cost=cost; mp[cnt].next=headlist[from]; headlist[from]=cnt++; mp[cnt].v=to; mp[cnt].cost=cost; mp[cnt].next=headlist[from]; headlist[from]=cnt++; } // void Spfa() { int i,j; for(i=0; i<n; ++i) { d[i]=INF; vis[i]=0; } d[start]=0; vis[start]=1; queue<int>q; q.push(start); while(!q.empty()) { int v==q.front(); q.pop(); vis[v]=0; for(i=headlist[v]; i!=-1; i=mp[i].next) { int b=mp[i].v; if(d[b]>d[v]+mp[i].cost) { d[b]=d[v]+mp[i].cost; if(!vis[b]) { vis[b]=1; q.push(b); } } } } int ans=-1; for(i=1; i<n; ++i) { if(d[u]>ans) ans=d[i]; } } int main() { //for(i=1; i<=n; i++) // headlist[i]=-1; memset(head,-1,sizeof(head)); cnt=0; cin>>from>>to>>cost; // Insert(edge1,head1,u,v,w); // Insert(edge2,head2,v,u,w); } ============================================================= Bellman_ford // 这种算法比较少用,不多介绍了 //不断进行松弛操作 void bellman_ford() { int i,j,start=1; for(i=1; i<=n; i++) d[i]=INF; d[start]=0; for (i=1; i<n; i++) { //重复进行n-1次收缩 for (j=0; j<m; j++) { //对每条边进行收缩 if (d[t[j].u]+t[j].w<d[t[j].v]) d[t[j].v]=d[t[j].u]+t[j].w; //分别对每条边的两个顶点分别进行收缩 if (d[t[j].v]+t[j].w<d[t[j].u]) d[t[j].u]=d[t[j].v]+t[j].w; } } //简单说就是不断进行松弛 int ans=-1; for(i=2; i<=n; i++) if(d[i]>ans) ans=d[i]; } int main() { m=0; t[m].u=; t[m].v=; t[m].w=; m++; }
- 版权声明:本文基于《知识共享署名-相同方式共享 3.0 中国大陆许可协议》发布,转载请遵循本协议
- 文章链接:http://www.carlstedt.cn/archives/644 (转载时请注明本文出处及文章链接)
相关文章
- 本文无相关文章
- 本文无相关文章
发表评论
快来吐槽一下吧!