最近图论的总结

这里是一些图的一些基础题目。
首先是dijkstra算法,也就是dijkstra求最短路径的问题。
这个一般是来解决 一个点到其他点最短路径的问题。

具体的做法是,设置一个数组d表示,每一个点到该点的最短距离。edge表示邻接矩阵,d初始化为
d[i]=edge[i][v],然后每次找d数组中最小的那个值,并且标记,然后更新d数组,假如新添加了一个k点,则对每一个可以比较的d,去进行d[k]+edge[k][i];

然后是floyd求最短路径,这个是求任意两点之间的最短距离。
方法是冬二维数组d[i][j]来表示i点到j点的最短距离,初始化时等于edge[i][j]。但要明白的是i到j点的最短距离可能是中间先到达别的一系列的点然后再到达k点,所以找出所有的情况。

void floyd()
{
    int i,j,k;
    for(i=0;i<v;i++)
        for(j=0;j<v;j++)
    {
        d[i][j]=edge[i][j];
        if(d[i][j]!=999)
            p[i][j]=ver[i]+ver[j];
        else
            p[i][j]="";
    }
    for(k=0;k<v;k++)
        for(i=0;i<v;i++)
        for(j=0;j<v;j++)
    {
        if(d[i][k]+d[k][j]<d[i][j])
        {
            d[i][j]=d[i][k]+d[k][j];
            p[i][j]=p[i][k]+ver[j];
        }
    }

}

kruskal算法求最小生成树

这种方法是按找边方法的,先找最短的那一条边,将两个顶点用并查集的方法合并为一条边,然后再去找最短的边,如果两个顶点分不是一个 根的话就合并,直到找到n-1条边为止

int inset(int v1)//找根
{
    int x=v1;
    while(p[x]>0)
        x=p[x];
    return x;
}
struct v
{
    int f,to;
    int w;
}e[502];
bool cmp(v a1,v a2)//按权值排序
{
    if(a1.w==a2.w)
        return a1.f<a2.f;
    else
        return a1.w<a2.w;

}
void kryskal()
{
    for(int i=1;i<=vnum;i++)
        p[i]=0;
        int num=1,v1,v2;
        for(int i=1;num<vnum;i++)
        {
            v1=inset(e[i].f);
            v2=inset(e[i].to);
            if(v1!=v2)
            {
                cout<<e[i].f<<" "<<e[i].to<<" ";
                p[v1]=v2;
                num++;
            }
        }
}

prim算法求最小生成树
这个是按找点的方法来建树,首先随便添加一个点定义l数组用来存别的点到该点的距离,找到最短距离,标记并更新,更新的方法是看剩余的点的距离与新加入点的距离比较,较小的取代

void prim(int v)
{
    int ad[1000],low[1000];
    for(int i=0;i<vnum;i++)
    {
        low[i]=edge[v][i];
    }
    low[v]=0;
    for(int i=1;i<vnum;i++)
    {
        int j=MIN(low);
        cout<<low[j]<<" ";
        low[j]=0;
        for(int i=0;i<vnum;i++)
        {
            if(edge[j][i]<low[i])
            {
                low[i]=edge[j][i];
            }
        }

    }
}

拓扑排序的输入,先输出入度为零的点然后,把该点到其他点的入度减一,重复就好了

void tsort()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        if(mapp[i][j]==1)
        rudu[j]++;
    for(int i=1;i<=n;i++)
    {
        int it=0;
        for(int j=1;j<=n;j++)
        {
            if(rudu[j]==0)
            {
                it=j;
                break;
            }
        }
        rudu[it]=-1;
        path[i]=it;
        for(int j=1;j<=n;j++)
           if(mapp[it][j]==1)
           rudu[j]--;
    }
}

拓扑图求关键路径

端点为事件,边为活动,用结构体存储w,用qd zd存储每一条边的开始和结束的点。然后去求
每个事件的最早发生时间和最晚发生时间

最早发生时间:首先端点0的最早发生时间是零
其次是其他所有点能到达他的点,的最短时间在加上到达他这个活动的时间的最大值。

最晚发生时间是,这个点能到的所有的店中的最晚发生时间减去活动的最小值

然后去找活动的最早和最晚时间

活动最早时间等于该边边起点的最短事件时间
活动最晚时间等于改变终点的最晚时间减去权值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值