图论的一些事儿 模版

最小生成树(求的就是给定一个无向图,挑选若干条边,连成一个树行图(无圈),使得所选边的权至和最小。)

Prim:

//prim算法

int prim(int n)
{
    int i,j,min,pos;
    int sum=0;
    memset(isvisited,false,sizeof(isvisited));
    //初始化
    for (i=1;i<=n;i++)
    {
        dist[i]=map[1][i];
    }
    //从1开始
    isvisited[1]=true;
    dist[1]=MAX;
    //找到权值最小点并记录下位置
    for (i=1;i<n;i++)
    {

        min=MAX;
        //pos=-1;
        for (j=1;j<=n;j++)
        {

            if (!isvisited[j] && dist[j]<min)
            {
                min=dist[j];
                pos=j;
            }
        }

        sum+=dist[pos];//加上权值
        isvisited[pos]=true;
        //更新权值
        for (j=1;j<=n;j++)
        {
            if (!isvisited[j] && dist[j]>map[pos][j])
            {
                dist[j]=map[pos][j];
            }
        }
    }
    return sum;

}


感悟: 最小生成树的代码与地杰斯特拉有着相像之处 ,prim算法是相加的是权重而地杰斯特拉增加的是下一个边

还有一种算法和prim的代码功能相同是kruskal,但是代码量大~

地杰斯特拉(求的是从一点到另一点的最短路径)(有向图)权值不能为负值

代码:

/***************************************
* About:    有向图的Dijkstra算法实现
***************************************/
 
#include <iostream>
using namespace std;
 
const int maxnum = 100;
const int maxint = 999999;
 
 
void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum])
{
    bool s[maxnum];    // 判断是否已存入该点到S集合中
    for(int i=1; i<=n; ++i)
    {
        dist[i] = c[v][i];
        s[i] = 0;     // 初始都未用过该点
        if(dist[i] == maxint)
            prev[i] = 0;
        else
            prev[i] = v;
    }
    dist[v] = 0;
    s[v] = 1;
 
    // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
    // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
    for(int i=2; i<=n; ++i)
    {
        int tmp = maxint;
        int u = v;
        // 找出当前未使用的点j的dist[j]最小值
        for(int j=1; j<=n; ++j)
            if((!s[j]) && dist[j]<tmp)
            {
                u = j;              // u保存当前邻接点中距离最小的点的号码
                tmp 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值