图的应用个人总结

图的应用

一、图的连通性问题

(一)无向图的连通分量

​ 在对图遍历时,对于连通图,无论是DFS还是BFS,只需要调用一次搜索过程,只需要从任意一个顶点出发,就可以遍历图中给每一个顶点。

​ 对于非连通图,需要多次调用搜索过程,每次调用所得到的顶点为每个连通分量中的顶点集。调用搜索的过程的次数就是该图连通分量的个数

(二)两个顶点之间的简单路径

​ 判断顶点u到v是否有简单路径

​ 从u开始进行DFS或BFS搜索,若访问到v则u,v间有简单路径

int pre[];//记录从第u个顶点到v的简单路径
void EasyPath(Graph *G,int u,int v){
    pre=(int *)malloc(G->vexnum*sizeof(int));
    for(int i=0;i<G->vexnum;i++){
        pre[i]=-1;//对pre数组进行初始化
    }
    pre[u]=-2;//将pre[u]初始化为-2,表示初始顶点u已经被访问,且没有前驱
    DFSPath(G,u,v);//使用深度优先搜索找到一条从u到v的简单路径
    free(pre);
}
bool DFSPath(Graph *G,int u,int v){
    int j;
    for(j=firstadj(G,u);j>=0;j=nextadj(G,u,j)){
        if(pre[j]==-1){
            pre[j]=u;
            if(j==v){
                PrintPath(pre,v);//从v开始沿着pre输出路径u到v
                return true;
            }else if(DFSPath(G,j,v)){
                return true;
            }
        }
    }
    return false;
}

(三)图的生成树与最小生成树

​ 一个连通图的生成树是指一个极小连通子图,它含有图的全部顶点,但是只有已连通n个顶点的n-1条边

(1)深度优先生成树
(2)广度优先生成树
(3)最小生成树

​ 对于连通的带权图,其生成树也是带权的,生成的树T的边的权值综和称为该树的权

​ W(T)=W(u,v)

最小生成树(MST):一个无向图G的最小生成树是由该图链接所有顶点的边构成的树,且总代价最小,值得注意的是MST不唯一。使用贪心选择策略,思路是先局部最优,再全局最优。

(四)普里姆Prim算法

​ 设图G=(V,E),生成树T的顶点集为U

​ (1)任取图中的一个顶点v0加入集合U

​ (2)在所有满足u属于U,V属于V-U的边(u,v)属于E中

​ 选择一个权重最小的边加入生成树T=T中

​ 将v0加入到U中

​ (3)重复(2)直到全部n个顶点均已加入到U集合中

​ 可见Prim算法是逐步增加U中的顶点,可称为加边法

#define MAXV
#define INF 32767
typedef struct{
    int no;//顶点编号
    InfoType info;//顶点信息(权重)
}VertexType;
typedef struct{ 
    int edges[MAXV][MAXV];//邻接矩阵,元素为权重
    VertexType vexs[MAXV];//存放顶点信息
    int n,e;//顶点数、边数
}MatGraph;

void Prim(MaxGraph *g,int v){
    int lowcost[MAXV];//记录顶点
    int closest[MAXV];//记录当前顶点邻接点的权值
    int i,j,k,min;
    for(i=0;i<g->n;i++){//初始化lowcost何closest数组
        lowcost[i]=g->edges[v][i];
        closest[i]=v;
    }
    for(i=1;i<g->n;i++){
        min=INF;
        //找最小权值
        for(j=0;j<g->n;j++){//在(V-U)中找出离U最近的顶点k
            if(lowcost[j]!=0 && lowcost[j]<min){
                min=lowcost[j];
                k=j;//k记录最近顶点编号
            }
        }
        printf("(%d,%d)-%d",closest[k],k,min);
        lowcost[k]=0;//赋值为0,标记k已经加入U
        
        for(j=0;j<g->n;j++){//修改数组lowcost和closest
        	if(lowcost[j]!=0 && g->edges[k][j]<lowcost[j]){//把原有邻接表的权重和lowcost数组的权重
            	lowcost[j]=g->edges[k][j];
            	closest[j]=k;
        	}
    	}
        
    }

}

Prim思路 局部最优+调整 = 全局最优(贪心算法)其算法时间复杂度为o(n^2)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值