西南科技大學OJ題 求最小生成樹(Prim算法)1075

求最小生成樹(Prim算法)

 1000(ms)

 10000(kb)

 2256 / 4495

Tags: 生成樹

求出給定無向帶權圖的最小生成樹。圖的定點爲字符型,權值爲不超過100的整形。在提示中已經給出了部分代碼,你只需要完善Prim算法即可。

#include< iostream> 
using namespace std; 

typedef struct 

int n; 
int e; 
char data[500]; 
int edge[500][500]; 
}Graph; 

typedef struct 

int index; 
int cost; 
}mincost; 

typedef struct 

int x; 
int y; 
int weight;    
}EDGE; 


typedef struct 

int index; 
int flag; 
}F; 

void create(Graph &G,int n ,int e) 

int i,j,k,w; 
char a,b; 
for(i=0;i< n;i++) 
cin>>G.data[i]; 
for(i=0;i< n;i++) 
for(j=0;j< n;j++) 

if(i==j) 
G.edge[i][j]=0; 
else 
G.edge[i][j]=100; 

for(k=0;k< e;k++) 

cin>>a; 
cin>>b; 
cin>>w; 
for(i=0;i< n;i++) 
if(G.data[i]==a) break; 
for(j=0;j< n;j++) 
if(G.data[j]==b) break; 

G.edge[i][j]=w; 
G.edge[j][i]=w; 

G.n=n; 
G.e=e; 

void Prim(Graph &G,int k) 

//完成Prim算法 

int main() 

Graph my; 
int n,e; 
cin>>n>>e; 
create(my,n,e); 
Prim(my,0);    
return 0; 

輸入


 

第一行爲圖的頂點個數n第二行爲圖的邊的條數e接着e行爲依附於一條邊的兩個頂點和邊上的權值

輸出


 

最小生成樹中的邊。

樣例輸入

6
10
ABCDEF
A B 6
A C 1
A D 5
B C 5
C D 5
B E 3
E C 6
C F 4
F D 2
E F 6

樣例輸出

(A,C)(C,F)(F,D)(C,B)(B,E)

 

 

 

#include<iostream>  
#include<stdio.h>//新加的頭文件 
using namespace std; 
typedef struct 

     int n; 
    int e; 
    char data[500]; 
    int edge[500][500]; 
}Graph; 
typedef struct 

    int index; 
    int cost; 
}mincost; 
typedef struct 

    int x; 
    int y; 
    int weight;    
}EDGE; 

typedef struct 

    int index; 
    int flag; 
}F; 
void create(Graph &G,int n ,int e) 

    int i,j,k,w; 
    char a,b; 
    for(i=0;i< n;i++) 
    cin>>G.data[i]; 
    for(i=0;i< n;i++) 
        for(j=0;j< n;j++) 
        { 
            if(i==j) 
            G.edge[i][j]=0; 
            else 
            G.edge[i][j]=100; 
        } 
    for(k=0;k< e;k++) 
    { 
        cin>>a; 
        cin>>b; 
        cin>>w; 
        for(i=0;i< n;i++) 
        if(G.data[i]==a) break; 
        for(j=0;j< n;j++) 
        if(G.data[j]==b) break; 
        G.edge[i][j]=w; 
        G.edge[j][i]=w; 
    } 
    G.n=n; 
    G.e=e; 

void Prim(Graph &G,int v) //將k改爲v; 

    int lowcost[100];//用來儲存相應序號的最短長度 
    int min;//用來標記長度 
    int closest[100],i,j,k;//closest作爲標記,並且記錄相應的點 
    for(i=0;i<G.n;i++)//將v=0,放入到樹中,將到其他點到0點的長度依次儲存在lowcost中 
    {
        lowcost[i]=G.edge[v][i];
        closest[i]=v;//將所有標記都賦值爲0,並且將closest【0】賦值爲相應的序號0! 
    }    
    for(i=1;i<G.n;i++)//已經將0點放入到樹中,還有G.n-1個點需要放入,所以從 i=1開始 
    {
        min=100;//初始化min 
        for(j=0;j<G.n;j++)//找出到放入樹中的點的長度中最短的長度,並且用k記錄該點 
        {
            if(lowcost[j]!=0&&lowcost[j]<min)
            {
                min=lowcost[j];
                k=j;
            }
        }
        printf("(%c,%c)",closest[k]+'A',k+'A');//輸出邊,因爲用相應的數字儲存的,但是要輸出字符,所以加上A的ascll碼,即爲相應的字母 
        lowcost[k]=0;//k點到樹的長度標記爲0,避免重複 ,並且k爲剛放入樹中的點 
        for(j=0;j<G.n;j++)
        {
            if(lowcost[j]!=0&&G.edge[k][j]<lowcost[j])//遍歷剛放入樹中的k那一行中是否有更短到樹的長度 
            {
                lowcost[j]=G.edge[k][j];//如果有,則將那個點到k點的長度儲存在lowcost中對應位置 
                closest[j]=k;//將closest對應位置儲存 相應序號。 
            }
        }
    }

int main() 

    Graph my; 
    int n,e; 
    cin>>n>>e; 
    create(my,n,e); 
    Prim(my,0);    
    return 0; 

/* 
#include<stdio.h>
int n;int map[100][100]={0};//初始化圖 
char str[100];int queue[100];
void Prim(int top)//top爲隊的長度 
{
    if(top<n)
    {
        int min=100,x,y;//初始化min的值,用來查找最小權重 
        for(int i=0;i<top;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(map[queue[i]][j]<min&&map[queue[i]][j]!=0)//依次遍歷隊中的點對應的行 如果不爲0,並且小於min,則改變min的值,並且記錄行和列 
                {
                    min=map[queue[i]][j];
                    x=queue[i];
                    y=j;
                }
            }
        }
        for(int k=0;k<n;k++)//將能到達y點的圖標記爲0 ,避免重複  
        {
            map[k][y]=0;
        }
        printf("(%c,%c)",str[x],str[y]);//輸出邊,即記錄的行和列 
        queue[top++]=y;//並且將其入隊 
        map[x][y]=0;//將該點的圖標記爲0,並且將其反向的點的圖也標記爲0 
        map[y][x]=0;
        Prim(top);//繼續遞歸直到所有的點都入隊爲止 
    }
}
int main()
{
    int e;
    scanf("%d",&n);
    scanf("%d",&e);
    scanf("%s",str);
    for(int i=0;i<e;i++)
    {
        char a,b;int data;
        getchar();//抵消回車字符 
        scanf("%c %c %d",&a,&b,&data);
        map[a-'A'][b-'A']=data;//將字符結點變成相應的序號結點,並且創建無向圖 
        map[b-'A'][a-'A']=data;
    }
    queue[0]=0;//將0點入隊 ,從0行開始遍歷 
    for(int k=0;k<n;k++)//將到達0點的圖標記爲0,避免重複 
    {
        map[k][0]=0;
    }
    Prim(1);//1位當前隊的長度 

*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章