#include<stdio.h> #include<string.h> const int INF = 0x3f3f3f; const int N = 105; /* 简述prim过程 1.初始化最小生成树(最开始只有一个点,这个点可以是任意一个点) 2.维护最小生成树,每次选取离原有生成树最近的点,并加入最小生成树, 然后用这个点更新其他点到最小生成树的距离(类似于松弛) */ int n,m; int data[N][N]; int prim(); int main() { scanf("%d %d", &n, &m); //点的数目和边得数目 for(int i =0; i <=n;i++) //初始化为一个极大值。(若两点之间没有连通,则用极大值替代) for(int j = 0; j <=n; j++) data[i][j] = INF; for(int i =0; i < m; i++) //prim用邻接矩阵建图(所以适用于稠密图) { int x,y,w; scanf("%d %d %d",&x, &y,&w); data[x][y] = data[y][x] = w; } int result = prim(); printf("%d\n",result); return 0; } int prim() { int dis[N],sum = 0; int mark[N] = {0}; int edge[N]; //edge[i] = j表示在生成树中,j的父亲是i; mark[1] = 1; for(int i = 1; i <= n; i++) { dis[i] = data[1][i]; edge[i] = 1; //初始化edge,刚开始生成树中只有点1,所以其他的点都指向点1 } for(int i =1; i < n; i++) { int min_val = INF; int min_id; for(int j = 1; j <=n; j++) { if(mark[j] == 0 && min_val > dis[j]) { min_val = dis[j]; min_id = j; } } sum += min_val; mark[min_id] = 1; if(data[edge[min_id]][min_id] > 0) printf("%d %d\n",edge[min_id],min_id); for(int k =1; k <= n; k++) { if(mark[k] == 0 && dis[k] > data[min_id][k]) { dis[k] = data[min_id][k]; edge[k] = min_id; //更新min_id的儿子; } } } return sum; }
prim模版(输出边)
猜你喜欢
转载自blog.csdn.net/u013377068/article/details/80069867
今日推荐
周排行