两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

1. 最小生成樹(又名:最小權(quán)重生成樹)

概念:將給出的所有點連接起來(即從一個點可到任意一個點),且連接路徑之和最小的圖叫最小生成樹。最小生成樹屬于一種樹形結(jié)構(gòu)(樹形結(jié)構(gòu)是一種特殊的圖),或者說是直鏈型結(jié)構(gòu),因為當(dāng)n個點相連,且路徑和最短,那么將它們相連的路一定是n-1條。

可以利用參考一個問題理解最小生成樹,有n個村莊,每個村莊之間距離不同,要求村莊之間修路,每一個村莊必須與任意一個村莊聯(lián)通,如何修路最省錢(修的最短)

2. 普利姆算法介紹

利姆(Prim)算法求最小生成樹,也就是在包含n個頂點的連通圖中,找出只有(n-1)條邊包含所有n個頂點的連通子圖,也就是所謂的極小連通子圖

具體過程如下:

(1)設(shè)G=(V,E)是連通網(wǎng),T=(U,D)是最小生成樹,V,U是頂點集合,E,D是邊的集合 

(2)若從頂點u開始構(gòu)造最小生成樹,則從集合V中取出頂點u放入集合U中,標(biāo)記頂點v的visited[u]=1

(3)若集合U中頂點ui與集合V-U中的頂點vj之間存在邊,則尋找這些邊中權(quán)值最小的邊,但不能構(gòu)成回路,將頂點vj加入集合U中,將邊(ui,vj)加入集合D中,標(biāo)記visited[vj]=1

(4)重復(fù)步驟②,直到U與V相等,即所有頂點都被標(biāo)記為訪問過,此時D中有n-1條邊

 

3. 代碼實現(xiàn)

不同的題目有不同的細(xì)節(jié)實現(xiàn)方式,因此本代碼僅供參考

#include <stdio.h>
#include <stdlib.h>
#define n 20
#define MaxNum 10000  /*定義一個最大整數(shù)*/
 
/*定義鄰接矩陣類型*/
typedef int adjmatrix[n + 1][n + 1];   
typedef struct {
    int fromvex, tovex;                 //生成樹的起點和終點
    int weight;                         //邊的權(quán)重
} Edge;
typedef Edge *EdgeNode;                 //定義生成樹的別名
int arcnum;     /*邊的個數(shù)*/
 
/*建立圖的鄰接矩陣*/
void CreatMatrix(adjmatrix GA) {
    int i, j, k, e;
    printf("=============================\n");
    printf("圖中有%d個頂點\n", n);
    for(i=1; i<=n; i++) {
        for(j=1; j<=n; j++) {
            if(i==j) {
                GA[i][j]=0;         /*對角線的值置為0*/
            } else {
                GA[i][j]=MaxNum;    /*其他位置的值置初始化為一個最大整數(shù)*/
            }
        }
    }
    printf("請輸入邊的個數(shù):\n");
    scanf("%d", &arcnum);
    printf("請輸入邊的信息,依照起點,終點,權(quán)值的形式輸入:\n");
    for(k=1; k<=arcnum; k++) {
        scanf("%d,%d,%d",&i,&j,&e);  /*讀入邊的信息*/
        GA[i][j]=e;
        GA[j][i]=e;
    }
}
 
/*初始化圖的邊集數(shù)組*/
void InitEdge(EdgeNode GE,int m) {
    int i;
    for(i=1; i<=m; i++) {
        GE[i].weight=0;
    }
}
 
/*依據(jù)圖的鄰接矩陣生成圖的邊集數(shù)組*/
void GetEdgeSet(adjmatrix GA,EdgeNode GE) {
    int i, j, k = 1;
    for(i=1; i<=n; i++) {
        for(j=i+1; j<=n; j++) {
            if(GA[i][j] !=0 && GA[i][j] != MaxNum) {
                GE[k].fromvex = i;
                GE[k].tovex = j;
                GE[k].weight = GA[i][j];
                k++;
            }
        }
    }
}
 
/*按升序排列圖的邊集數(shù)組*/
void SortEdge(EdgeNode GE,int m) {
    int i,j,k;
    Edge temp;
    for(i=1; i<m; i++) {
        k=i;
        for(j=i+1; j<=m; j++) {
            if(GE[k].weight > GE[j].weight) {
                k=j;
            }
        }
        if(k!=i) {
            temp = GE[i];
            GE[i]=GE[k];
            GE[k]=temp;
        }
    }
}
 
/*利用普里姆算法從初始點v出發(fā)求鄰接矩陣表示的圖的最小生成樹*/
void Prim(adjmatrix GA,EdgeNode T) {
    int i,j,k,min,u,m,w;
    Edge temp;
    /*給T賦初值。相應(yīng)為v1依次到其余各頂點的邊*/
    k=1;
    for(i=1; i<=n; i++) {
        if(i!=1) {
            T[k].fromvex=1;
            T[k].tovex=i;
            T[k].weight=GA[1][i];
            k++;
        }
    }
    /*進行n-1次循環(huán),每次求出最小生成樹中的第k條邊*/
    for(k=1; k<n; k++) {
        min=MaxNum;
        m=k;
        for(j=k; j<n; j++) {
            if(T[j].weight<min) {
                min=T[j].weight;
                m=j;
            }
        }
        /*把最短邊對調(diào)到k-1下標(biāo)位置*/ 可用swap替換
        temp=T[k];
        T[k]=T[m];
        T[m]=temp;
        /*把新增加最小生成樹T中的頂點序號賦給j*/
        j=T[k].tovex;
        /*改動有關(guān)邊,使T中到T外的每個頂點保持一條到眼下為止最短的邊*/
        for(i=k+1; i<n; i++) {
            u=T[i].tovex;
            w=GA[j][u];
            if(w<T[i].weight) {
                T[i].weight=w;
                T[i].fromvex=j;
            }
        }
    }
}
 
/*輸出邊集數(shù)組的每條邊*/
void OutEdge(EdgeNode GE,int e) {
    int i;
    printf("依照起點,終點。權(quán)值的形式輸出的最小生成樹為:\n");
    for(i=1; i<=e; i++) {
        printf("%d,%d,%d\n",GE[i].fromvex,GE[i].tovex,GE[i].weight);
    }
    printf("=============================\n");
}
 
int main() {
    adjmatrix GA;
    Edge GE[n*(n-1)/2], T[n];
    CreatMatrix(GA);
    InitEdge(GE,arcnum);
    GetEdgeSet(GA,GE);
    SortEdge(GE,arcnum);
    Prim(GA,T);
    printf("\n");
    OutEdge(T,n-1);
    return 0;
}


點贊(0)

C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:

一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程

解決困擾你多年的C語言疑難雜癥特性的C語言進階課程

從零到寫出一個爬蟲的Python編程課程

只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程

信息學(xué)奧賽或C++選手的 必學(xué)C++課程

藍橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程

手把手講解近五年真題的藍橋杯輔導(dǎo)課程

Dotcpp在線編譯      (登錄可減少運行等待時間)