注册 登录
编程论坛 C语言论坛

克鲁斯卡尔算法 为啥老是成环呀 求大佬帮助

waiting; 发布于 2019-06-23 17:47, 957 次点击
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

#define OK 1
#define ERROR 0
#define Max_Int 32726
#define MVNum 100
 
typedef int Status;
typedef int ArcType;
typedef char VerTexType;
 
struct ed{
    VerTexType Head;//边的始点
    VerTexType Tail;//边的终点
    ArcType lowcost;//边的权值
}Edge[MVNum];
 
typedef struct{
    VerTexType vex[MVNum];//顶点表
    ArcType arc[MVNum][MVNum];//邻接矩阵
    int arcnum, vexnum;//顶点数和边数
}AMGraph;

//****************************************

int LocateVex(AMGraph *G, VerTexType v)//下标位置的查找
{
    int i;
    for (i = 0; i < G->vexnum; i++)
    {
        if (G->vex[i] == v)
            return i;
    }
    return -1 ;
}

/***************************************
void DispGraph (AMGraph &G)
{   
    int i , j ;
    printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf ("\n输出邻接矩阵的信息:\n\n");

    for (i = 0 ; i<G.arcnum ; i++);
        printf ("%9d",G.vex[i]);
    printf ("输出邻接矩阵:\n");

    for(i=0;i<G.arcnum;i++)
        {
            for(j=0;j<G.arcnum;j++)
                {
                if(G.arc[i][j]==Max_Int)
                    printf("%8s", "0");
                else
                    printf("%8d",G.arc[i][j]);
                }
        printf("\n");   
    }
}

//***************************************/
 
Status CreateUDN(AMGraph *G)//创建无向网
{
    printf ("建设 1.上海、2.北京、3.南京、4.扬州、5.南通、6.苏州等 六城市之间的交通线路(数字即为城市代号):\n");

    VerTexType v1, v2;
    ArcType w;//w为权值即建设费用
    int i, j, k;
    printf("输入总城市数、总拟定的路数:");
    scanf("%d %d", &G->vexnum, &G->arcnum);
    printf("输入各个城市代号值:");
        fflush(stdin);
    for (i = 0; i < G->vexnum; i++)
    {
        scanf("%c", &G->vex[i]);
    }
    for (i = 0; i < G->vexnum; i++)
        for (j = 0; j < G->vexnum; j++)
            {
                G->arc[i][j] = Max_Int;  //将各值置位无穷大
            }
    for (k = 0; k < G->arcnum; k++)
    {
        fflush(stdin) ;
        printf("依次输入相连道路两个城市代号以及建路的费用:");
        scanf("%c %c %d", &v1, &v2, &w);
        Edge[k].Head = v1;
        Edge[k].Tail = v2;
        Edge[k].lowcost = w;
        i = LocateVex(G, v1);//查找该城市代号在总的数组中的位置
        j = LocateVex(G, v2);
        G->arc[i][j] = w;  //相应的俩城市之间的道路建设费用
        G->arc[j][i] = G->arc[i][j];//无向图故而两城市之间道路互通
    }


    return OK;
}

//*******************************************************

void Sort(AMGraph &G) //将所输入的两城市代码以及建设费用按费用进行排序
{
    int i, j, addr;
    ArcType min;
    ed temp;//定义结构体temp
    for (i = 0; i < G.arcnum; i++)
    {
        min = Edge[i].lowcost;  //将第一个权值赋值给min
        addr = i;
        for (j = i + 1; j < G.arcnum; j++)
        {
            if (min>Edge[j].lowcost)  //不断的比较互换
            {
                min = Edge[j].lowcost;
                addr = j;
            }//将最小权值换位到i的位置
        }
        if (addr != i)//若符合整个结构体进行位置互换
        {
            temp = Edge[i];
            Edge[i] = Edge[addr];
            Edge[addr] = temp;
        }
    }
}

//*******************************************************


void MiniSpanTree_Kruskal(AMGraph &G)//应用Kruskal算法进行建立
{
    int i, j,v1,v2,vs1,vs2;//vs1 vs2表示连通分量
    int sum=0 , k=0;
    int Vexset[MVNum];
    ed rets[MVNum] ;
    Sort(G);
    for (i = 0; i < G.vexnum; ++i)
        Vexset[i] = i;
    printf ("最经济方案为:\n");
    for (i = 0; i < G.vexnum;++i)
    {
        v1 = LocateVex(&G, Edge[i].Head);//v1为始点的下标
        v2 = LocateVex(&G, Edge[i].Tail);//v2为终点的下标
        vs1 = Vexset[v1];
        vs2 = Vexset[v2];
        if (vs1 != vs2)//边的连个顶点分属两个不同的连通分量
        {
            printf("%c->%c--%d\n", Edge[i].Head, Edge[i].Tail ,Edge[i].lowcost);
            for (j = 0; j < G.vexnum; ++j)
                if (Vexset[j] == vs2)
                    Vexset[j] = vs1;
            sum += Edge[i].lowcost ;
        }
        
    }
    printf ("最经济方案费用为:%d\n",sum);
}


int main()
{
    AMGraph G;
    CreateUDN(&G);
/*    DispGraph (G) ;
    for (i=0 ; i<G.arcnum ;i++)
        for (j=0 ; j<G.arcnum ;j++)
            if (G.arc[i][j]==Max_Int)
                printf ("0");
            else
                printf ("%d",G.arc[i][j]);*/
    MiniSpanTree_Kruskal(G);
    return 0;
}
0 回复
1