zoukankan      html  css  js  c++  java
  • 图论最短路问题和最小生成树问题的区别

    图论最短路问题和最小生成树问题的区别

    区别:

    一 区别
    最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。
    最短路径是从一点出发,到达目的地的路径最小。
    图论最短路问题——一个人的旅行
    最小生成树问题——Agri-Net

    图论最短路

    包含dijkstra,spfa,Floyd
    最短路dijkstra代码:

    //最短路——Dijkstra
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAX_V = 205;
    int edge[MAX_V][MAX_V] ;
    int dis[MAX_V];
    bool vis[MAX_V];
    int N,A,B;
    
    void Dijkstra()
    {
        int tmp,pos;
        memset(vis,false,sizeof(vis));
        for (int i = 1;i <= N;i++)
        {
           dis[i] = edge[A][i];   //从哪里开始寻找
        }
        dis[A] = 0;
        for (int i = 2;i <= N;i++)
        {
           tmp = INF;        //重新寻找
           for (int j = 1;j <= N;j++)
           {
               if (!vis[j] && tmp > dis[j])  //找到最小的权值
               {
                  tmp = dis[j];
                  pos = j;
               }
           }
           if (tmp == INF)   break; //没有找的,直接进入下一个的寻找
           vis[pos] = true; //标记已经找过的点
           for (int j = 1;j <= N;j++)  //更新周围的点的权值
           {
               if (dis[pos] + edge[pos][j] < dis[j])
               {
                  dis[j] = dis[pos] + edge[pos][j];
               }
           }
        }
        printf("%d
    ",dis[B] == INF?-1:dis[B]);
    }
    
    
    int main()
    {
        while (~scanf("%d",&N) && N)
        {
           int tmp;
           for (int i = 0;i <= N;i++)
           {
               for (int j = 0;j <= i;j++)
               {
                  if (i == j)   edge[i][j] = edge[j][i] = 0;
                  else   edge[i][j] = edge[j][i] = INF;
               }
           }
           scanf("%d%d",&A,&B);
           for (int i = 1;i <= N;i++)
           {
               scanf("%d",&tmp);
               if (i - tmp > 0)
               {
                  edge[i][i-tmp] = 1;
               }
               if (i + tmp <= N)
               {
                  edge[i][i+tmp] = 1;
               }
           }
           Dijkstra();
        }
        return 0;
    }
      
    
    

    Floyd(不太理解)

    
    for(k=1;k<=n;k++)   
      for(i=1;i<=n;i++)   
          for(j=1;j<=n;j++)   
     			if(e[i][j]>e[i][k]+e[k][j])   
         		e[i][j]=e[i][k]+e[k][j]; 
    
    //实质就是动态规划
    
    
    

    最小生成树

    一.kruskal算法
    二.prim算法

    
    **最小生成树——prim算法**
     
    
    /*计算最小生成树的一种方法是使其连续地一步步长成。在每一步,都要把一个节点当做根并往上加边,这样也就把相关联的顶点加到增长中的树上。
    在算法的任一时刻,我们都可以看到一个已经添加到树上的顶点集,而其余顶点尚未加到这颗树中。此时,算法在每一阶段都可以选择边(u,v),使得(u,v)的值是所有u在树上但v不在树上的边的值中的最小者,而找出一个新的顶点并把它添加到这棵树中。图指出该算法如何从v1开始构建最小生成树。开始时,v1在构建中的树上,它作为树的根但没有边。每一步添加一边和一个顶点到树上。*/
    
    int prim()
    {
    	memset(dis,INF,sizeof(dis));
    	memset(vis,false,sizeof(vis));
    	for (int i = 1;i <= N;i++)
    	{
    		dis[i] = edge[i][1];
    	} 
    	dis[1] = 0;
    	vis[1] = true;
    	int res = 0;
    	for (int i = 1;i <= N - 1;i++)
    	{
    		int tmp = INF,pos;
    		for (int j = 1;j <= N;j++)
    		{
    			if (!vis[j] && tmp > dis[j])
    			{
    				tmp = dis[j];
    				pos = j;
    			}
    		}
    		if (tmp == INF) return 0;
    		vis[pos] = true;
    		res += dis[pos];
    		for (int j = 1;j <= N;j++)
    		{
    			if (!vis[j] && edge[pos][j] < dis[j]) //注意最短路与生成树的更新条件很相似
    			{
    				dis[j] = edge[pos][j];
    			}
    		}
    	}
    	return res;
    }
    
    
    
    
  • 相关阅读:
    关于QQ秀
    c#重点知识解答(五) 选择自 masterall 的 Blog
    c#.net常用函数和方法集 选择自 fineflyak 的 Blog
    JavaScript 中 substr 和 substring的区别
    C#重点知识详解(二) 选择自 masterall 的 Blog
    c#重点知识详解(六) 选择自 masterall 的 Blog
    转:一个男孩的自白
    win2003端口映射2003的路由与远程访问,做端口映射(转)
    渗透笔记(转载)
    win下配置的Apache+PHP+MySQL绿色版本(转)
  • 原文地址:https://www.cnblogs.com/fzuljz/p/5701303.html
Copyright © 2011-2022 走看看