dijkstra算法模板_HDU3790

问题描述:  有n个点,m个边,每条边上有一个权值,求从s节点到e节点的最短路径,即途径路上的权值和为最小。

      是求单起点,多终点最短路的问题。

dijkstra算法基本思想

1:设置一个distanse数组,存储从起始点s到各个节点的距离(权值和),distanse[i]即从s到i的最短路

2:初始状态,distanse[i]=mp[s][i],found[s]=1

3:每次从所有 1未访问的节点中  挑出 2distanse最小的点k  choose() 进行松弛操作;

4:松弛操作。如果经过k到j的distanse小于原来的distanse  更新distanse

  if(dis[k]+mp[k][j]<dis[j])   dis[j]=dis[k]+mp[k][j];

dijkstar 算法的时间复杂度是O(N^2)可以用对优化到O(N*LogN)级别

    用了贪心的思想,只能用于正权边,带负权的会导致贪心的bug

本题是两个权,距离和cost,分优先级的进行dijkstra,比较水。

不过还是要注意数组下标别写错了,错一个就是WA!

dijkstra算法只有两个过程 1:选择下一个要操作的点    2:松弛

对图的存储使用  邻接矩阵  和  链式前向星 (感觉和邻接表是一回事)都是一样的,只要稍微改一下代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn = 1005 , INF = 0x3f3f3f;
 5 int mp[maxn][maxn],dis[maxn],fond[maxn],cost[maxn][maxn],wei[maxn];
 6 int n,m,a,b,d,p,s,t;
 7
 8 void input()
 9 {
10     while(m--)
11     {
12         scanf("%d%d%d%d",&a,&b,&d,&p);
13         if(mp[a][b]>d)
14         {
15             mp[a][b]=mp[b][a]=d;
16             cost[a][b]=cost[b][a]=p;
17         }
18         else if(mp[a][b]==d)
19         {
20             cost[a][b]=cost[b][a]=min(cost[a][b],p);
21         }
22     }
23     cin>>s>>t;
24 }
25
26 int choose()
27 {
28     int cnt = -1,minn=INF;
29     for(int i=1;i<=n;i++)
30     {
31         if(!fond[i]&&minn>dis[i])
32         {
33             minn=dis[i];
34             cnt=i;
35         }
36     }
37     return cnt;
38 }
39
40 void dijkstra()
41 {
42     for(int i=1;i<=n;i++)
43     {
44         fond[i]=0;
45         dis[i]=mp[s][i];
46         wei[i]=cost[s][i];
47     }
48     fond[s]=1;
49     for(int i=1;i<=n;i++)
50     {
51         int k=choose();
52         if(k==-1)return ;
53         fond[k]=1;
54         for(int j=1;j<=n;j++)
55         {
56             if(!fond[j])
57             {
58                 if(dis[k]+mp[k][j]<dis[j]){
59                     dis[j]=dis[k]+mp[k][j];
60                     wei[j]=wei[k]+cost[k][j];
61                 }
62                 else if( dis[j]==dis[k]+mp[k][j])
63                 {
64                     wei[j]=min(wei[j],wei[k]+cost[k][j]);
65                 }
66             }
67         }
68     }
69 }
70
71 int main()
72 {
73     while(cin>>n>>m,n,m)
74     {
75         memset(mp,INF,sizeof(mp));
76         memset(cost,INF,sizeof(cost));
77         input();
78         dijkstra();
79         cout<<dis[t]<<" "<<wei[t]<<endl;
80     }
81     return 0;
82 }

时间: 2024-08-01 10:45:46

dijkstra算法模板_HDU3790的相关文章

HDU 2544 最短路(我的dijkstra算法模板、SPAFA算法模板)

思路:这道题是基础的最短路径算法,可以拿来试一下自己对3种方法的理解 dijkstra主要是从第一个点开始枚举,每次枚举出当当前最小的路径,然后再以那最小的路径点为起点,求出它到其它未标记点的最短距离 bellman-ford 算法则是假设有向网中有n 个顶点.且不存在负权值回路,从顶点v1 和到顶点v2 如果存在最短路径,则此路径最多有n-1 条边.这是因为如果路径上的边数超过了n-1 条时,必然会重复经过一个顶点,形成回路:而如果这个回路的权值总和为非负时,完全可以去掉这个回路,使得v1到v

最短路径---dijkstra算法模板

dijkstra算法模板 http://acm.hdu.edu.cn/showproblem.php?pid=1874 1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<stdlib.h> 6 #include<algorithm> 7 #include<queue> 8 #include&

Dijkstra算法模板

1 #include<iostream> 2 #include<cstring> 3 #include<vector> 4 using namespace std; 5 struct edge{ 6 int to, cost; 7 edge(int t, int c): to(t),cost(c) { 8 //empty body 9 } 10 }; 11 void addEdge(vector<vector<int> > &G,vect

迪杰斯特拉/dijkstra 算法模板(详细注释)

#include <iostream> #include <malloc.h> #include <cstring> #include <stack> #include <cstdio> //定义邻接矩阵的大小 #define N 100 #define M 100 using namespace std; typedef struct node { int map[N][M];//邻接矩阵 int n;//顶点数 int e;//边数 }MGr

迪杰斯特拉/dijkstra 算法模板(具体凝视)

#include <iostream> #include <malloc.h> #include <cstring> #include <stack> #include <cstdio> //定义邻接矩阵的大小 #define N 100 #define M 100 using namespace std; typedef struct node { int map[N][M];//邻接矩阵 int n;//顶点数 int e;//边数 }MGr

hdu 2851 dijkstra算法变形

dijkstra算法模板: Int visited[i]//结点i若被访问则为1,没有则为0 Int dist[i]// 目前结点j到其他各结点的最短路的长度 Int w[i][j]//边(i,j)的权值 初始化:(结点1~n) memset(v,0,sizeof(v)); dist[j]=0; dist[i]=inf;(i>=1&&i<=n&&i!=j) cin>>a>>b>>x; if(w[a][b]>x)//a到b

hdu2544 最短路 Dijkstra算法

最短路(Dijkstra算法模板题) Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 96778    Accepted Submission(s): 41849借鉴链接:https://blog.csdn.net/UncleJokerly/article/details/79703622 Problem Description 在每年的

Dijkstra算法——超~~详细!!

Dijkstra算法_ ** 时隔多月,我又回来了!**_ 今天下午久违的又学了会儿算法,又重新学习了一遍Dijkstra,这是第三次重新学习Dijkstra(*以前学的都忘完了>_<*). 废话先不bb,上代码. #include<bits/stdc++.h> using namespace std; #define INF 9999999 #define M 1000 int d[M]; int p[M]={0}; int con[M][M]; int n,line; //n点

单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 设road[i][j]表示相邻的i到j的路长U集合存储已经求得的到源点最短路径的节点,S集合表示还没求得的节点dis[i]表示i到源节点(设为0)的最短路径vis[i]=1表示i节点在U集合中 刚开始dis[0]=0,vis[0]=1;dis[i]=maxn,vis[i]=0;for 1 to