//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
今日推荐
周排行