Prim算法和Dijkstra算法(个人感觉有一点相同)

https://www.cnblogs.com/CheeseZH/archive/2012/10/09/2717106.html

之前一直觉得Prim和Dijkstra很相似,但是没有仔细对比;

今天看了下,主要有以下几点:

1:

Prim是计算最小生成树的算法,比如为N个村庄修路,怎么修花销最少。

Dijkstra是计算最短路径的算法,比如从a村庄走到其他任意村庄的距离。

2:

Prim算法中有一个统计总len的变量,每次都要把到下一点的距离加到len中;

Dijkstra算法中却没有,只需要把到下一点的距离加到cls数组中即可;

3:

Prim算法的更新操作更新的cls是已访问集合到未访问集合中各点的距离;

23              for (j=0;j<n;j++)
24              {
25                  if (!visited[j] && map[j][nid]<adjset[j])//更新条件:j点未访问,加入新点后已访问集合到j的距离变小了
26                  {
27                      adjset[j] = map[j][nid];
28                  }
29              }

Dijkstra算法的更新操作更新的cls是源点到未访问集合中各点的距离,已经访问过的相当于已经找到源点到它的最短距离了;

20         for (j=1;j<=n;j++)
21        {

22             if(!vis[j]&&map[nxt][j]<MAX&&(min+map[nxt][j])<cls[j])//更新条件:j点未访问,新点与j点之间有路,
23                 cls[j]=cls[nxt]+map[nxt][j];
24         }

Prim算法

复制代码

 1          //初始化
 2          memset(visited,0,sizeof(visited));
 3          visited[0] = 1;
 4          len = 0;
 5          for (i=0;i<n;i++)    adjset[i] = map[i][0];
 6          //Begin
 7          for (i=1;i<n;i++)
 8          {
 9              //找到下一条符合条件的点
10              nlen = MAX;
11              for (j=0;j<n;j++)
12              {
13                  if (!visited[j] && adjset[j]<nlen)
14                  {
15                      nlen = adjset[j];
16                      nid = j;
17                  }
18              }
19              //访问找到的那个点
20              len += nlen;
21              visited[nid] = 1;
22              //更新邻接距离
23              for (j=0;j<n;j++)
24              {
25                  if (!visited[j] && map[j][nid]<adjset[j])
26                  {
27                      adjset[j] = map[j][nid];
28                  }
29              }

复制代码

Dijkstra算法

复制代码

 1 void Dijkstra(int v)
 2 {
 3     int i,j,min,nxt;
 4     for(i=1;i<=n;i++)    cls[i]=map[v][i];
 5     memset(vis,0,sizeof(vis));
 6     vis[v]=1;
 7     for (i=1;i<n;i++)
 8     {
 9         min=MAX;
10         nxt=v;
11         for (j=1;j<=n;j++)
12         {
13             if(!vis[j]&&cls[j]<min)
14             {
15                 nxt=j;
16                 min=cls[j];
17             }
18         }
19         vis[nxt]=1;
20         for (j=1;j<=n;j++)
21         {
22             if(!vis[j]&&map[nxt][j]<MAX&&(min+map[nxt][j])<cls[j])
23                 cls[j]=cls[nxt]+map[nxt][j];
24         }
25     }
26 }

 

http://lx.lanqiao.cn/problem.page?gpid=T32 

 

转自 https://www.cnblogs.com/chensunrise/p/4367270.html 

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
#define PI acos(-1.0)
#define eps 1e-8
#define LL long long
#define MEM(a,b) memset(a,b,sizeof(a))
#define PB push_back
#define MP make_pair
#define PQ priority_queue
#define MII map<int,int>::iterator
#define MLL map<LL,LL>::iterator
#define pii pair<int,int>
#define SI set<int>::iterator
#define SL set<LL>::iterator
#define MSI map<string,int>::iterator
#define M_SI multiset<int>::iterator
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
#define BUG printf("bug************bug************bug\n");

using namespace std;

#define maxn 100000+10

struct node
{
    int id,cost;
    node(){}
    node(int id,int cost):id(id),cost(cost){}
};

vector<node>G[maxn];
LL ans[maxn];

void init()
{
    ans[0]=0;
    for (int i=1;i<maxn;i++) {G[i].clear();ans[i]=ans[i-1]+i+10; }
}

priority_queue<pii,vector<pii>,greater<pii> >q;

int d[maxn],n;
bool vis[maxn];

void dijkstra(int k)
{
    for(int i=0;i<=n;i++) d[i]=(i==k? 0 : inf);
    
    memset(vis,0,sizeof(vis));

    q.push(make_pair(d[k],k));
    
	while(!q.empty())
    {
        pii u=q.top();
    
	    q.pop();
    
	    int x=u.second;
    
	    if(!vis[x]) {
            vis[x]=true;
            for (int i=0;i<G[x].size();i++)
            {
                if(d[G[x][i].id]>d[x]+G[x][i].cost)
                {
                    d[G[x][i].id]=d[x]+G[x][i].cost;
                    q.push(make_pair(d[G[x][i].id],G[x][i].id));
                }
            }
        }
    }
}
int main()
{
    int n, x, y, c;

    while(scanf("%d", &n)!=EOF)
    {
        init();
        
        for (int i=1;i<=n;i++) 
			d[i]=inf;
			
        for (int i=1;i<n;i++)
        {
            scanf("%d%d%d", &x, &y, &c);
            G[x].PB(node(y,c));
            G[y].PB(node(x,c));
        }
        d[1] = 0;
        
        dijkstra(1);
        
		int dist=0,u;
        
		for (int i=1;i<=n;i++) 
			if (d[i]>dist) dist=d[i],u=i;
        
		for(int i=1;i<=n;i++) d[i]=inf;
        
		d[u]=0;
        
		dijkstra(u);
        
		dist=0;
        
		for (int i=1;i<=n;i++) dist=max(dist,d[i]);
        
		printf("%I64d\n",ans[dist]);
    }
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Prim算法Dijkstra算法是两种常用的图算法,用于解决不同的问题。 1. Prim算法Prim算法是一种用于构建最小生成树的贪心算法。它从一个起始顶点开始,逐步扩展最小生成树的边,直到包含所有顶点为止。具体步骤如下: - 选择一个起始顶点作为最小生成树的根节点。 - 从根节点开始,选择与当前最小生成树相连的边中权值最小的边,并将其加入最小生成树。 - 重复上一步,直到最小生成树包含所有顶点。 2. Dijkstra算法Dijkstra算法是一种用于求解单源最短路径的算法。它可以计算出从一个起始顶点到其他所有顶点的最短路径。具体步骤如下: - 初始化起始顶点的最短路径为0,其他顶点的最短路径为无穷大。 - 选择一个未访问的顶点中最短路径最小的顶点作为当前顶点。 - 更新当前顶点相邻顶点的最短路径,如果经过当前顶点到达相邻顶点的路径比已知的最短路径更短,则更新最短路径。 - 重复上一步,直到所有顶点都被访问。 下面是一个使用Prim算法Dijkstra算法的示例代码: ```python # Prim算法 def prim(graph, start): visited = set() min_span_tree = [] visited.add(start) while len(visited) < len(graph): min_edge = None for u in visited: for v in graph[u]: if v[0] not in visited and (min_edge is None or v[1] < min_edge[1]): min_edge = (v[0], v[1], u) min_span_tree.append(min_edge) visited.add(min_edge[0]) return min_span_tree # Dijkstra算法 def dijkstra(graph, start): distances = {v: float('inf') for v in graph} distances[start] = 0 visited = set() while len(visited) < len(graph): min_distance = float('inf') min_vertex = None for v in graph: if v not in visited and distances[v] < min_distance: min_distance = distances[v] min_vertex = v visited.add(min_vertex) for neighbor, weight in graph[min_vertex]: if distances[min_vertex] + weight < distances[neighbor]: distances[neighbor] = distances[min_vertex] + weight return distances # 示例图 graph = { 'A': [('B', 5), ('C', 1)], 'B': [('A', 5), ('C', 2), ('D', 1)], 'C': [('A', 1), ('B', 2), ('D', 4), ('E', 8)], 'D': [('B', 1), ('C', 4), ('E', 3), ('F', 6)], 'E': [('C', 8), ('D', 3)], 'F': [('D', 6)] } # 使用Prim算法构建最小生成树 min_span_tree = prim(graph, 'A') print("Prim算法最小生成树:", min_span_tree) # 使用Dijkstra算法求解单源最短路径 distances = dijkstra(graph, 'A') print("Dijkstra算法最短路径:", distances) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值