最短路 dijkstra算法 poj2387 bellman_ford spfa

来源:互联网 发布:mysql5.7数据库下载 编辑:程序博客网 时间:2024/05/22 00:09

最短路 dijkstra算法 poj2387 bellman_ford spfa

就是一个模板题,,,,,,,,,,,啊? 模板题 这个还要套模板?     一脸门鼻  

直接上代码

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define inf (0x7f7f7f7f)const int maxn=100005;struct Edge{int from,to,dist;}eg;int T,n;vector<Edge>edges;//边 vector<int>g[maxn];//存储边在edges上的编号  bool done[maxn];int d[maxn];int p[maxn];struct node{      int d,u;      bool operator < (const node &a) const {          return d>a.d;    }  }temp,now;//利用优先队列 优化dijkstra算法 void init(int n)//初始化 {for(int i=1;i<=n;i++)g[i].clear();edges.clear(); }void AddEdge(int from,int to,int dist)//vector建立边比较快  {int m;eg.from=from;eg.to=to;eg.dist=dist;edges.push_back(eg);m=edges.size();g[from].push_back(m-1); }void dijkstra(int s){priority_queue<node>qu;for(int i=1;i<=n;i++) d[i]=inf;//初始化无穷大 注意加减的时候不要溢出 d[s]=0;temp.d=0,temp.u=s; memset(done,false,sizeof(done));qu.push(temp);//源点入队 while(!qu.empty()){now=qu.top();qu.pop();int u=now.u;if(done[u])continue;done[u]=true;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];temp.d=d[e.to];temp.u=e.to;qu.push(temp);}}}}int main(){scanf("%d%d",&T,&n);for(int i=0;i<T;i++){int from,to,dist;scanf("%d%d%d",&from,&to,&dist);AddEdge(from,to,dist);//双向边AddEdge(to,from,dist);}dijkstra(n);printf("%d",d[1]); } 

下面是bellman_ford 如果不是判别负值圈 比dijkstra要慢很多 但是内存占用少

#include<iostream>#include<cstdio>using namespace std;#define MAX 0x3f3f3f3f#define N 10100int u[N],v[N],w[N],T,n;int d[N];bool bellman_ford(){for(int i=1;i<=n;i++)d[i]=(i==n)?0:MAX;for(int i=1;i<=n-1;i++)for(int j=1;j<=2*T;j++)松弛{int x=u[j],y=v[j];if(d[x]<MAX) d[y]=min(d[y],d[x]+w[j]);}return true;}int main(){scanf("%d%d",&T,&n);for(int i=1;i<=T*2;i+=2){//要存两边要不然松弛是错的scanf("%d%d%d",&u[i],&v[i],&w[i]);u[i+1]=v[i];v[i+1]=u[i];w[i+1]=w[i];}bellman_ford();printf("%d",d[1]);}

下面是spfa 队列优化bellman_ford算法

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define inf (0x7f7f7f7f)const int maxn=100005;struct Edge{int from,to,dist;}eg;int T,n;vector<Edge>edges;//边 vector<int>g[maxn];//存储边在edges上的编号  bool inq[maxn];int d[maxn];int p[maxn],cnt[maxn];void init(int n)//初始化 {for(int i=1;i<=n;i++)g[i].clear();edges.clear(); }void AddEdge(int from,int to,int dist)//vector建立边比较快  {int m;eg.from=from;eg.to=to;eg.dist=dist;edges.push_back(eg);m=edges.size();g[from].push_back(m-1); }bool spfa(int s){queue<int>qu;memset(inq,0,sizeof(inq));memset(cnt,0,sizeof(cnt));for(int i=1;i<=n;i++) d[i]=inf;//初始化无穷大 注意加减的时候不要溢出 d[s]=0;inq[s]=true;qu.push(s);//源点入队 while(!qu.empty()){int u=qu.front();qu.pop();inq[u]=false;for(int i=0;i<g[u].size();i++){Edge& e=edges[g[u][i]];if(d[u]<inf && d[e.to]>d[u]+e.dist)//如果新找到的点的距离小于原来找到的 {d[e.to]=d[u]+e.dist;p[e.to]=g[u][i];if(!inq[e.to]){qu.push(e.to);inq[e.to]=true;if(++cnt[e.to]>n)return false;}}}}}int main(){scanf("%d%d",&T,&n);for(int i=0;i<T;i++){int from,to,dist;scanf("%d%d%d",&from,&to,&dist);AddEdge(from,to,dist);AddEdge(to,from,dist);}spfa(n);printf("%d",d[1]); } 

从上到下 依次是 spfa-> bellman-> dijkstra




0 0
原创粉丝点击