链接城市最小生成树

//Graphziv画图软件

//文件

#include<stdio.h>

#include<string.h>
#include<stdlib.h>
#define FINITY 20000 // FINITY 表示无穷大
#define M 100 //顶点数
typedef  int edgetype; //边的权值类型


typedef  char vertextype; //顶点值类型


typedef struct {
vertextype  vexs[M];//顶点信息域
edgetype    edges[M][M];//邻接矩阵
int n,e; //图的顶点总数与边数
}mgraph;


typedef struct edgedata
{
int beg,en;
int length;
}edge;
edge tree[100];
typedef struct G
{
    char begin;
    char end;
    int quanzhi;
    int num;
}Tree;
typedef struct W
{
    int begin;
    int end;
    int quanzhi;
    int num;
}Tree1;


   Tree1 tree1[50];//zhu
   Tree tree2[100];//prim
   Tree tree3[50];


void creat (mgraph *g,char *s,int c);


void prim(mgraph g,edge tree[M-1]);






void creat (mgraph *g,char *s,int c) // C=0 表示建立无向图
{
int i,j,k,w;
FILE *rf;
rf = fopen(s,"r");//从文件中读取图的边信息
if(rf)
{
fscanf(rf,"%d%d",&g->n,&g->e);//读入图的顶点数和边数
printf("%d\t%d\n",g->n,g->e);
for(i=0;i < g->n;i++)//读入图的顶点值
fscanf(rf,"%1s",&g->vexs[i]);
for(i=0;i < g->n;i++)//初始化邻接矩阵
for(j=0;j < g->n;j++)
if(i==j)
g->edges[i][j]=0;
else
g->edges[i][j]=FINITY;
        int n2=0;
for(k=0;k < g->e;k++)//读入网络中的边
{
fscanf(rf,"%d%d%d",&i,&j,&w);
tree1[k].begin=i;
tree1[k].end=j;
tree1[k].quanzhi=w;
g->edges[i][j]=w;
if(c==0){
//建立无向图邻接矩阵




   g->edges[j][i]=w;
}
n2++;


}
tree1[1].num=n2;
//printf("")
// int i;
//printf("%d",tree1[1].num);


//for(i=0;i<tree1[1].num;i++)
  //  {
   //     printf("%c",tree1[i].begin);
    //    printf("%c",tree1[i].end);
       // fprintf(fp,"%c%s%c%s",x,str,y,tem);
   // }
fclose(rf); //关闭文件
}
else
g->n=0;
}










void prim(mgraph g,edge tree[M-1])
{
edge x;
int d,min,j,k,s,v;
for(v=1;v<=g.n-1;v++)//建立初始入选点,并初始化生成树边集tree
{
tree[v-1].beg=0;//此处从顶点V0开始求最小生成树
tree[v-1].en=v;
tree[v-1].length=g.edges[0][v];
}
for(k=0;k<=g.n-3;k++)  //依次求当前(第k条边)最小两栖边,并加入tree
{
min=tree[k].length;
s=k;


for(j=k+1;j<=g.n-2;j++)
if(tree[j].length<min)
{
min=tree[j].length;
s=j;
}
v=tree[s].en; //入选顶点为v
x=tree[s]; //通过交换,将当前最小边加入tree中
tree[s]=tree[k];
tree[k]=x;
for(j=k+1;j<=g.n-2;j++)//由于新顶点V的加入,修改两栖边的基本信息
{
d=g.edges[v][tree[j].en];
if(d<tree[j].length)
{
tree[j].length=d;
tree[j].beg=v;
}
}
}
printf("\nthe minimum cost spanning tree is:\n");//输出最小生成树
int n=0;
for(j=0;j<=g.n-2;j++)
{




printf("\n%c---%c %d\n",g.vexs[tree[j].beg],g.vexs[tree[j].en],tree[j].length);
tree2[j].begin=g.vexs[tree[j].beg];
tree2[j].end=g.vexs[tree[j].en];
// strcpy(tree2[j].begin,g.vexs[tree[j].beg]);
        // strcpy(tree2[j].end,.vexs[tree[j].en]);
tree2[j].quanzhi=tree[j].length;
n++;


}
tree2[1].num=n;
//int i;
//printf("%d",tree2[1].num);


// for(i=0;i<tree2[1].num;i++)
  //  {
  //      printf("%c",tree2[i].begin);
  //      printf("%c",tree2[i].end);
       // fprintf(fp,"%c%s%c%s",x,str,y,tem);
  //  }
printf("\nthe root of it is %c\n",g.vexs[0]);
}




void quicksort(edge edges[],int left,int right)
{
    edge x;
    int i,j,flag=1;
    if(left<right)
    {
        i=left;
        j=right;
        x=edges[i];
        while(i<j)
        {
            while(i<j&&x.length<edges[j].length)j--;
            if(i<j)edges[i++]=edges[j];
            while(i<j&&x.length>edges[i].length)i++;
            if(i<j)edges[j--]=edges[i];
        }
        edges[i]=x;
        quicksort(edges,left,i-1);
        quicksort(edges,i+1,right);


    }
}
void  getedge(mgraph g,edge edges[] )
{
    int i,j,k=0;
    for(i=0;i<g.n;i++)
    for(j=0;j<i;j++)
    if(g.edges[i][j]!=0&&g.edges[i][j]<FINITY)
    {
        edges[k].beg=i;
        edges[k].en=j;
        edges[k++].length=g.edges[i][j];


    }
}
void kruskal(mgraph g)
{
    int i,j,k=0,ltfl;
    int cnvx[M];
    edge edges[M*M];
    edge tree[M];
    getedge(g,edges);
    quicksort(edges,0,g.e-1);
    for(i=0;i<g.n;i++)
    cnvx[i]=i;
    for(i=0;i<g.n-1;i++)
    {




         while (cnvx[edges[k].beg]==cnvx[edges[k].en])
         k++;
         tree[i]=edges[k];
         ltfl=cnvx[edges[k].en];
         for(j=0;j<g.n;j++)
             if(cnvx[j]==ltfl)
              cnvx[j]=cnvx[edges[k].beg];
         k++;


    }
    printf("最小生成树是\n");
    int n=0;
    for(j=0;j<g.n-1;j++){
    printf("%c---%c%6d\n",g.vexs[tree[j].beg],g.vexs[tree[j].en],tree[j].length);
    tree3[j].begin=g.vexs[tree[j].beg];
tree3[j].end=g.vexs[tree[j].en];
tree3[j].quanzhi=tree[j].length;
n++;
    }
    tree3[1].num=n;




}
 int prin2(mgraph g)//zong
{
    FILE *fp;


    edge tree[M];
    char str[100],tem[100],dot[100];
    char ch,filename[20];
    printf("请输入所用文件名:");
    scanf("%s",filename);
    if((fp=fopen(filename,"w"))==NULL)
        {
                printf("无法打开文件!");
                exit(0);


        }


    int i,j;
    char x,y,a,b;
    strcpy(dot,"[style=dotted];");
    strcpy(tem,"[dir=none];");
    strcpy(str,"->");
    fputs("digraph{",fp);
    for(i=0;i<tree1[1].num;i++)
    {
        x=tree1[i].begin+'a';
        y=tree1[i].end+'a';
        fprintf(fp,"%c%s%c",x,str,y);
        fputs("[label=",fp);
        fprintf(fp,"%d",tree1[i].quanzhi);
        fputs("]",fp);
        fprintf(fp,"%s",tem);
    }
    fputs("}",fp);


}
  int prin(mgraph g)
{
    FILE *fp;


    edge tree[M];
    char str[100]={"->"};
    char tem[100]={"[dir=none];"};
    char dot[100]={"[style=dotted];"};
    char ch,filename[20];
    printf("请输入所用文件名:");
    scanf("%s",filename);
    if((fp=fopen(filename,"w"))==NULL)
        {
                printf("无法打开文件!");
                exit(0);


        }


    int i,j;
    char x,y,a,b;
    char x1[20];
    char y1[20];
    fputs("digraph{",fp);
    for(i=0;i<tree2[1].num;i++)
    {
        x=tree2[i].begin;
        {


    char key[20];
    if(x=='a')
     {


         strcpy(key,"datong");
         strcpy(x1,key);


     }


   else if(x=='b')
     {


         strcpy(key,"taiyuan");
          strcpy(x1,key);


     }
   else  if(x=='c')
     {


         strcpy(key,"shuozhou");
          strcpy(x1,key);


     }
   else  if(x=='d')
     {


         strcpy(key,"xinzhou");
          strcpy(x1,key);


     }
   else  if(x=='e')
     {


         strcpy(key,"yangquan");
          strcpy(x1,key);


     }
   else  if(x=='f')
     {


         strcpy(key,"lvliang");
          strcpy(x1,key);


     }
  else   if(x=='g')
     {


         strcpy(key,"linfen");
          strcpy(x1,key);


     }
  else   if(x=='h')
     {


         strcpy(key,"yuncheng");
          strcpy(x1,key);


     }
   else  if(x=='i')
     {


         strcpy(key,"changzhi");
          strcpy(x1,key);


     }
  else   if(x=='j')
     {


         strcpy(key,"jincheng");
          strcpy(x1,key);


     }
       }




        y=tree2[i].end;
        {
            {


    char key2[20];
    if(y=='a')
     {


         strcpy(key2,"datong");
         strcpy(y1,key2);


     }


   else if(y=='b')
     {


         strcpy(key2,"taiyuan");
          strcpy(y1,key2);


     }
   else  if(y=='c')
     {


         strcpy(key2,"shouzhou");
          strcpy(y1,key2);


     }
   else  if(y=='d')
     {


         strcpy(key2,"xinzhou");
          strcpy(y1,key2);


     }
   else  if(y=='e')
     {


         strcpy(key2,"yangquan");
          strcpy(y1,key2);


     }
   else  if(y=='f')
     {


         strcpy(key2,"lvliang");
          strcpy(y1,key2);


     }
  else   if(y=='g')
     {


         strcpy(key2,"linfen");
          strcpy(y1,key2);


     }
  else   if(y=='h')
     {


         strcpy(key2,"yuncheng");
          strcpy(y1,key2);


     }
   else  if(y=='i')
     {


         strcpy(key2,"changzhi");
          strcpy(y1,key2);


     }
  else   if(y=='j')
     {


         strcpy(key2,"jincheng");
          strcpy(y1,key2);


     }
       }
        }


        fprintf(fp,"%s%s%s",x1,str,y1);
        fputs("[label=",fp);
        fprintf(fp,"%d",tree2[i].quanzhi);
        fputs("]",fp);
        fprintf(fp,"%s",tem);
    }
    fputs("}",fp);


}
 int prin3(mgraph g)
{
    FILE *fp;


    edge tree[M];
    char str[100]={"->"};
    char tem[100]={"[dir=none];"};
    char dot[100]={"[style=dotted];"};
    char ch,filename[20];
    printf("请输入所用文件名:");
    scanf("%s",filename);
    if((fp=fopen(filename,"w"))==NULL)
        {
                printf("无法打开文件!");
                exit(0);


        }


    int i,j;
    char x,y,a,b;
    fputs("digraph{",fp);
    for(i=0;i<tree3[1].num;i++)
    {
        x=tree3[i].begin;
        y=tree3[i].end;
        fprintf(fp,"%c%s%c",x,str,y);
        fputs("[label=",fp);
        fprintf(fp,"%d",tree3[i].quanzhi);
        fputs("]",fp);
        fprintf(fp,"%s",tem);
    }
    fputs("}",fp);


}
/*
int menu()
{
      printf("+++++++++++++欢迎进入城市最小联通系统+++++++++++++++");






     printf("\n\n\n\n\n");
      printf("1.***************加载城市数据****************\n");
      printf("2.***************显示城市布局****************\n");
      printf("3.***************PRIM构造********************\n");
      printf("1.***************显示PRIM构造结果************\n");
      printf("4.***************KRUSKAL构造*****************\n");
      printf("1.***************显示KRUSKAL构造结果*********\n");
        printf("\n\n\n\n");
        printf("++++++欢迎回来++++++\n");




}
int main()
{


    mgraph g;
    edge tree[M-1]; //用于存放最小生成树的M-1条边
    char filename[20];
    menu();
    printf("请输入图的文件名\n");
    gets(filename);
    creat(&g,filename,0);
    prim(g);
    kruskal(g);
    printf("\n");
    printf("全部的图:\n");
    prin2(g);
    printf("prim的图:\n");
    prin(g);
    printf("kruskal的图:\n");
    prin3(g);


    return 0;






}
*///这段不用


int main()
{


    mgraph g;       //定义图文件
    edge tree[M-1]; //用于存放最小生成树的M-1条边
    char filename[20];     //保存输入的文件名
    int i,j=1,k=1;
    while(j==1)     //一级菜单(可以返回)
    {
        printf("\n\n\n\n");
        printf("***********欢迎进入构造城市最小连通图程序***********\n\n\n\n");
        printf("\t\t 1.  加载城市数据 \n\n");
        printf("\t\t 2.  显示城市布局\n\n");
        printf("\t\t 3.  构造最小生成树\n\n");
        printf("\t\t 4.  退出程序 \n\n");
        printf("\n");
        printf("****************************************************\n");
        printf("\t 请选择操作选项( 1 ~ 4 ),按回车结束:\n\n\n");
        scanf("%d",&i);
        getchar();
        switch(i)
        {
            case 1:
                {
                    printf("请输入图的文件名\n");
                    gets(filename);
                    creat(&g,filename,0);              //创建图文件
                    printf("加载成功\n\n\n");break;
                }
            case 2:
                {
                    printf("城市布局:\n\t");       //以图片的格式输出图文件
                    prin2(g);
                    printf("保存成功\n\n\n");break;
                }
            case 3:     //构造最小生成树的二级菜单
                {
                    while(k==1)    //二级菜单可返回重复执行
                    {
                        printf("\n\n\n");
                        printf("*****************构造最小生成树*********************\n\n\n\n");
                        printf("\t 1.  使用PRIM算法构造最小生成树并保存地图\n\n");
                        printf("\t 2.  使用KRUSKAL算法构造最小生成树并保存地图\n\n");
                        printf("\t 3.  返回主菜单 \n\n");
                        printf("\n");
                        printf("****************************************************\n");
                        printf("\t 请选择操作选项( 1 ~ 3 ),按回车结束:\n\n\n\n\n\n\n");
                        scanf("%d",&i);
                        getchar();
                        switch(i)
                        {
                            case 1:
                                {
                                    prim(g,tree);       //prim算法构造最小生成树并以图片的格式保存
                                    prin(g);
                                    printf("构造完成并保存成功\n\n");break;
                                }
                            case 2:
                                {
                                    kruskal(g);     //kruskal算法构造最小生成树并以图片的格式保存
                                    prin3(g);
                                    printf("构造完成并保存成功\n\n");break;
                                }
                            case 3:
                                {k=0;break;}        //结束二级菜单并返回一级菜单
                            default: printf("输入错误!\n请重新输入操作选项(1~3)");
                        }
                    }
                    k=1;        //重新给k赋值,使生成树的二级菜单能够多次执行
                    break;
                }
            case 4:
                {
                    j=0;
                    printf("\n\n\n\n\n\n\n\n\n\n\t\t谢谢使用!\n\t\t  再见!\n\n\n\n\n\n\n\n");break;}
            default: printf("输入错误!\n请输入操作选项(1~5)");
        }
    }
    return 0;






}





猜你喜欢

转载自blog.csdn.net/qq_26577455/article/details/50552634