dj的邻接矩阵实现

#include <bits/stdc++.h>
using namespace std;
const int maxn=100,bignum=100001;
int g[maxn][maxn],dis[maxn],t[maxn],siz;
bool state[maxn];
void creat(int k)
{
    memset(g,0,sizeof(g));
    for(int i=0;i<=siz;i++)
    {
        for(int j=0;j<=siz;j++)
        {
            cin>>g[i][j];
        }
    }
    for(int i=0;i<=siz;i++)
    {
        dis[i]=g[k][i];

    }
    memset(state,true,sizeof(state));
    state[k]=false;
    memset(t,0,sizeof(t));
    t[k]=-1;
}
void addnode(int k)
{
    siz++;
    int cur;
    for(int i=0;i<=siz;i++)
    {
        cin>>cur;
        g[siz][i]=cur;
        g[i][siz]=cur;
    }
    dis[siz]=g[k][siz];
}
int findminandstate()
{
    int minpos,minsum=bignum;
    for(int i=0;i<=siz;i++)
    {
        if(state[i]==true)
        {
            if(dis[i]<minsum)
            {
                minpos=i;
                minsum=dis[i];
            }
        }

    }

    return minpos;
}
void dj(int k)
{
    int lastpos=k;
    for(int j=0;j<=siz;j++)
    {
        if(j==k)continue;
        int minpos=findminandstate();


        for(int i=0;i<=siz;i++)
        {
            if(state[i]&&((g[minpos][i]+dis[minpos])<dis[i]))
            {
                state[minpos]=false;
                dis[i]=g[minpos][i]+dis[minpos];
                t[i]=minpos;

            }
        }
    }
}
int main()
{
    int k;
    cin>>siz>>k;
    siz--;k--;
    creat(k);
    addnode(k);
    dj(k);
     for(int i=0;i<=siz;i++)cout<<t[i]+1<<" ";
     cout<<endl;
     for(int i=0;i<=siz;i++)cout<<dis[i]<<" ";
    return 0;
}
void prtg()
{
    for(int i=0;i<=siz;i++)
    {
        for(int j=0;j<=siz;j++)
        {
            cout<<g[i][j]<<" ";
        }
        cout<<endl;
    }
}
/*
6 1
0 50 100000 40 25 10
50 0 15 20 100000 25
100000 15 0 10 20 100000
40 20 10 0 10 25
25 100000 20 10 0 55
10 25 100000 25 55 0

5 1
0 50 100000 40 25
50 0 15 20 100000
100000 15 0 10 20
40 20 10 0 10
25 100000 20 10 0
10 25 100000 25 55 0
*/

maxn:可放的最大节点数,因为以邻接矩阵存储所以开一个较小的数

              Bignum:代码中用的大数,防止int溢出设一个不大不小的100001

              g:邻接矩阵,存放输入数据

              dis:存储节点到根节点距离的数组

              t:存储最小生成树

              siz:存储输入的邻接矩阵大小

              state;存储某个节点是否已挂上生成树,真表示未挂上

creat():一次性读入某个邻接矩阵

addnode():增加节点,需要在调用dj之前使用,不知道能有什么卵用

findminandstate():中间函数,用来找没挂上生成树的离源最近节点

dj():dj]



大概回忆一下dj的思路

目的:求一个边带权有向图中单源的最小生成树

思路的第一步:对于图中一个节点vi,它所邻接到的所有点中,把邻接边权值最小的那个点记作vk,则e=vi-vk一定是最小生成树上的一条边

                          呃这么写以后肯定看不懂再见,那就通俗的来说,想从甲地到乙地,我们有一条路直接从甲到乙,我们还有很多条别的路能直接到不知道什么鬼的地方。而这条直接从甲到乙的路比别的路的<甲地到第一个下车口的距离>还要短,那么显然,不走从甲到乙的这条直接的路的都在绕弯子

    这个第一步的用处在于:每一次从图上选择一个据起点最近的点,从起点到它的那条路肯定是在所需的树上的。

   那么为了能一步步走下去,我们需要一个数组,保存目前从起点到每一个节点的距离。目前没有发现有路的,就记作无限远。

  还有一个就是,每一次确定了一个点后,需要记录下这个确定的状态,以后找点的时候就可以忽略这个点了,同样用一个数组来存。

  这样一来就可以如此描述:

             起始步:将所有起点邻接到的节点,将这个边的长度作为目前起点到这个点的距离记录到数组里。

            循环步:对目前距起点最近且未挂上树的节点,挂上树,并且对这个节点邻接到的所有点便利一次,若<这个点到某个点的边权值>+<起点到这个点的距离>小于<此处的<某个点>到起点的距离>,那么就把<此处的<某个点>到起点的距离>更新为<这个点到某个点的边权值>+<起点到这个点的距离>

循环终止条件:所有节点都挂上树了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值