ACM最小生成树模版

            前几天去忙蓝桥杯省赛了唉,好几天没写博客了。不知道在那个算法群里看到大佬说3个填空题就可以获奖了。。。全程做选择题,结果后面没时间,有一个大题都没来得及看题目,还有一题怂了,明明最近都是写图论却还是怕图论。。。唉,打这种差一点的水漂打得难受。今天把学弟群里的专题拿去刷了,最小生成树。PS:不得不说,学弟真的tql。。。

        最小生成树:

在数据结构里学了prime算法(入顶点),kruskal算法(入边),说实话,离散数学里就有这个了,那个时候觉得破圈法真的太简单了(kruskal),但是代码老是有点忘记,没办法秒写。。。

先码出我自己写的kruskal和prime算法的模版:

kruskal算法:

#include
#include
using namespace std;
#define INF 3000	
struct Edge		//边的结构体 
{
	int a,b,cost;		//(a,b)边的权cost 
}p[10000+5];		//边的集合,等会用于排序 
int parent[100+5];		//并查集,将每个联通分量都用最上方的根表示 
bool com(Edge a,Edge b)
{
	return a.cost

kruskal算法最关键的就是①判连通②连通两个分量

①判连通的解决方法是用并查集,将同一个连通分量变成一个树,查询的时候一直查到根位置,若根相同,则两个分量是同一个连通分量,若不同则不是。比较难理解的压缩路径(之前老是忽略这一步),是在查询连通分量的时候将根变为最上方的根,一直往上爬,将连通分量中除了根节点外,其余的父亲结点都为根节点

②连通两个分量的方法简单,只需要将一个分量的树结构的根变成另一个分量的树结构的根的儿子即可。

prime算法:

#include  
#include  
#include  
using namespace std;  
#define maxn 30 
#define inf  100000
int road[maxn][maxn];		//邻接矩阵 
int dis[maxn];  			//判断行,从中取出最小点加入vis 
bool vis[maxn];  		//true代表已经纳入,false代表是为纳入 
int n;  
void prim()  
{  
    int minn, v;  
    for(int i = 0; i < n; i++)  
    {  
        dis[i] = road[0][i];  		//每个点与起点的距离 
        vis[i] = false;  
    }  
    for(int i = 1; i <= n; i++)//包括第一个点在内,一共要纳入n个点  
    {  
        min = inf;  
        for(int j = 0; j < n; j++)
        {  
            if(!vis[j] && minn > dis[j])  //每次找出未纳入顶点集与已知顶点集构成的权值最小的一条边  
            {  
                v = j;  
                minn = dis[j];  
            }  
        }  
        vis[v] = true;//把该顶点纳入已知集合  ,v就是未纳入顶点最短距离的点 
        for(int j = 0; j < n; j++)//更新与未纳入集合中的顶点的边的最小权值  
        {  
            if(vis[j]==false && dis[j] > road[v][j])	//未纳入 且  每个点与起点的距离大于新纳入的顶点v的距离 
                dis[j] = road[v][j];  //更新新的短距离 
        }  
    }  
    int ans;
    for(int i = 1; i < n; i++)  
        ans += dis[i];  		//将每个点(除起点)的距离累加   
    printf("%d\n",ans);
} 
int main()  
{  
    int n;    
    while(~scanf("%d",&n)&&n!=0)  
    {  
        for(int i = 0; i < n; i++)  		//初始化邻接矩阵 
            road[i][i] = 0;  
        for(int i = 1; i < n; i++)  //构造邻接矩阵 
        {  
        	for(int j=1;j<=n;j++)
            scanf("%d",&road[i][j]);  
        }
		/*for(int i=0;i

最小生成树专题训练:https://vjudge.net/contest/216338

你可能感兴趣的:(ACM模版)