题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544
题目大意:找点1到点n的最短路(无向图)
练一下最短路。。。
dijkstra+队列优化:
1 #include<iostream> 2 #include<functional> 3 #include<vector> 4 #include<queue> 5 using namespace std; 6 typedef pair<int, int> p;//first是最短距离,second是顶点编号 7 const int N = 105; 8 const int INF = 1 << 29; 9 10 struct edge { 11 int to, cost;//邻接的点,以及到该点的权值 12 }; 13 14 vector<edge>eg[N];//邻接表 15 bool used[N];//表示是否已被使用过 16 int d[N];//最短距离 17 int V, E;//顶点数和边数 18 19 void dijistra(int s) { 20 //优先队列,按first从小到大顺序 21 priority_queue<p, vector<p>, greater<p> >q; 22 //初始化 23 for (int i = 1; i <= V; i++) { 24 d[i] = INF; 25 used[i] = false; 26 } 27 d[s] = 0; 28 29 q.push(p(0, s)); 30 while (!q.empty()) { 31 p p1 = q.top(); 32 q.pop(); 33 int v = p1.second; 34 if (used[v]) continue; 35 used[v] = true; 36 for (int i = 0; i<eg[v].size(); i++) { 37 edge e = eg[v][i]; 38 if (d[e.to]>d[v] + e.cost) { 39 d[e.to] = d[v] + e.cost; 40 q.push(p(d[e.to], e.to)); 41 } 42 } 43 } 44 } 45 46 int main() { 47 while (cin >> V >> E && (V || E)) { 48 for(int i=1;i<=V;i++){ 49 eg[i].clear(); 50 } 51 for (int i = 1; i <= E; i++) { 52 int a, b, cost; 53 cin >> a >> b >> cost; 54 edge g1, g2; 55 g1.to = b, g2.to = a; 56 g1.cost = g2.cost = cost; 57 eg[a].push_back(g1); 58 eg[b].push_back(g2); 59 } 60 dijistra(1); 61 cout << d[V] << endl; 62 } 63 }
bellman-ford:
1 /* 2 bellman-ford 3 */ 4 #include<iostream> 5 #include<cstring> 6 using namespace std; 7 const int N=100005; 8 const int INF=1<<30; 9 10 struct edge{ 11 int from,to,cost; 12 }es[N];//边 13 14 int d[N];//出发点到i的最短距离 15 int V,E;//顶点数、边数 16 17 //求解从顶点s出发到所有点的最短距离 18 void shortest_path(int s){ 19 for(int i=1;i<=V;i++) d[i]=INF; 20 d[s]=0; 21 while(true){ 22 bool update=false; 23 for(int i=1;i<=E;i++){ 24 edge e=es[i]; 25 if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost){ 26 d[e.to]=d[e.from]+e.cost; 27 update=true; 28 } 29 //双向 30 if(d[e.to]!=INF&&d[e.from]>d[e.to]+e.cost){ 31 d[e.from]=d[e.to]+e.cost; 32 update=true; 33 } 34 35 } 36 if(!update) break; 37 } 38 } 39 40 int main(){ 41 int n,m; 42 while(cin>>V>>E&&(V||E)){ 43 for(int i=1;i<=E;i++){ 44 cin>>es[i].from>>es[i].to>>es[i].cost; 45 } 46 shortest_path(1); 47 cout<<d[V]<<endl; 48 } 49 }
floyd:
1 /*floyd*/ 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 const int N=105; 6 const int INF=1<<29; 7 int map[N][N];//map[i][j]表示边i~j的距离 8 9 int V,E;//顶点数,边数 10 11 void floyd(){ 12 for(int k=1;k<=V;k++) 13 for(int i=1;i<=V;i++) 14 for(int j=1;j<=V;j++) 15 map[i][j]=min(map[i][j],map[i][k]+map[k][j]); 16 } 17 18 int main(){ 19 while(cin>>V>>E&&(V||E)){ 20 for(int i=1;i<=V;i++){ 21 for(int j=1;j<=V;j++){ 22 if(i==j) 23 map[i][j]=0; 24 else 25 map[i][j]=INF; 26 } 27 } 28 for(int i=1;i<=E;i++){ 29 int a,b,cost; 30 cin>>a>>b>>cost; 31 map[a][b]=map[b][a]=cost; 32 } 33 floyd(); 34 cout<<map[1][V]<<endl; 35 } 36 }
spfa:
1 /*spfa*/ 2 #include<iostream> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int N=105; 7 const int INF=1<<29; 8 9 int map[N][N]; 10 int d[N];//距离起点最小距离 11 bool used[N];//点是否在队列中 12 int V,E;//顶点数,边数 13 14 //求解从顶点s出发到所有点的最短距离 15 void spfa(int s){ 16 //初始化 17 for(int i=1;i<=V;i++){ 18 d[i]=INF; 19 used[i]=false; 20 } 21 d[s]=0; 22 23 queue<int>q; 24 q.push(s); 25 used[s]=true; 26 while(!q.empty()){ 27 int k=q.front(); 28 q.pop(); 29 used[k]=false; 30 //此处实际上可以不用遍历所有点,能够用邻接表优化 31 for(int i=1;i<=V;i++){ 32 if(d[i]>d[k]+map[k][i]){ 33 d[i]=d[k]+map[k][i]; 34 //这个点更新后要入队,要判断是否已经在队列中 35 if(!used[i]){ 36 q.push(i); 37 used[i]=true; 38 } 39 } 40 } 41 } 42 } 43 44 int main(){ 45 while(cin>>V>>E&&(V||E)){ 46 //初始化 47 for(int i=1;i<=V;i++) 48 for(int j=1;j<=V;j++) 49 map[i][j]=(i==j?0:INF); 50 51 for(int i=1;i<=E;i++){ 52 int a,b,cost; 53 cin>>a>>b>>cost; 54 map[a][b]=map[b][a]=cost; 55 } 56 spfa(1); 57 cout<<d[V]<<endl; 58 } 59 } 60
时间: 2024-10-12 18:00:02