Prim最小生成树 实验报告含源码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告
题目说明:POJ2395 Out of Ray
题目大意:Beth有m个农场,农场之间有些相通,有些不通。
已知,Beth每一英里要一盎司的水,Beth希望走遍所有的农场但携带最少的水。
问:Beth最多需要带多少水?(每个农场都可以补充水)
本程序利用Prim算法俩实现题目要求。
1.<创建>
输入农场数和农场之间的距离(均为整数),程序给出连通判断。
2.修改路径
按格式输入修改值,此时路线可能会改变。
3.<输出最大携带水量>,附上最小生成树
实验说明:
1.基本思想
利用邻接表G [ ][ ] 储存农场信息,然后使用Prim算法来完成最小生成树的构建;最后寻找出最大边,如果农场是不连通的将给出提示,可以对路径修改。
2.函数模块
(1)int InitiTable(int G[][MaxFarm],int num);//创建邻接表,返回值是农场数目{
int j,k,TempValue;
while(true)
{
cout<<"请输入农场的数目:"<<' ';
cin>>num;
if(num<=MaxFarm&&num>0)
break;
cout<<"错误!请重新输入."<<endl<<endl;
}
for(j=0;j<num;j++)
{
for(k=0;k<num;k++)
{
if(j==k)
G[j][k]=MaxWeight;
else if(j<k)
{
while(true)
{
cout<<"请输入农场"<<j+1<<"至农场"<<k+1<<"的距离。
如果该路不存在请输入-1:"<<endl;
cin>>TempValue;
if(TempValue>=-1&&TempValue<MaxWeight) break;
cout<<"输入无效,请重新输入。
"<<endl;
}
if(TempValue==-1)
TempValue=MaxWeight;
G[j][k]=G[k][j]=TempValue; //保持无向图矩阵的对称性
}
}
}
return num ;
}
(2)int LinkJudge(int G[][MaxFarm],int num);//连通的判断
{
int linkjug,j,k;
for(j=0;j<num;j++)
{
linkjug=0;
for(k=0;k<num;k++)
if(G[j][k]<MaxWeight)
{linkjug=1;break;}
if(linkjug==0)
break;
}
if(!linkjug)
cout<<"农场是不连通的,无法计算!"<<endl;
return linkjug;
}
(3)void find(int G[][MaxFarm],int in[],int num, int path[MaxFarm][2]);
{ //这是主要的函数,用来生成最小生成树
int start=0,i,j,k,v1,v2,min=MaxWeight;
while(true)
{
cout<<"请选择出发农场:"<<endl;
cin>>start;
if(start>0 &&start<=num)
break;
cout<<"输入错误!请确认后重新输入."<<endl<<endl;
}
in[start-1]=1;
for(i=0;i<num-1;i++)//这里只进行num-1次的循环,即对剩下num-1个数说明
{
for(j=0;j<num;j++)
for(k=0;k<num;k++)//对结点的每个连通值进行判断
if(G[j][k]<min&&in[j]&&(!in[k]))
//(判断有连通值;进行第二次时判断连接的值没被标记;判断本身未标记;)
{v1=j;v2=k;min=G[j][k];}//记录最小值min,一次循环后可知最小值if(!in[v2])
{
path[i][0]=v1;
path[i][1]=v2;
in[v1]=1;
in[v2]=1;
min=MaxWeight;
}
}
}
(4)void Modify(int T[][MaxFarm],int num);//修改
{ int j,k,t1,t2,t3;//t1,t2,t3是修改用的
cout<<"现有路径如下:"<<endl;
for(j=0;j<num;j++)
{ for(k=0;k<num;k++)
{ if(k%5==0 &&k!=0)cout<<endl;
if(T[j][k]==100) cout<<j+1<<"-"<<k+1<<":None\t";
else cout<<j+1<<"-"<<k+1<<":"<<T[j][k]<<" \t";}
cout<<endl<<"-----------------------------------------------------------------"<<endl;
}
cout<<"<修改>格式(不存在请输入-1):1-2:-1 (路径长度)"<<endl;
while(true)
{scanf("%d-%d:%d",&t1,&t2,&t3);if(t3>=-1&&t3<MaxWeight) break;
cout<<"输入无效,请重新输入。
"<<endl;}
if(t3==-1)//说明:如果距离为-1,则输出为none,不连通
T[t1-1][t2-1]=T[t2-1][t1-1]=MaxWeight;
else
T[t1-1][t2-1]=T[t2-1][t1-1]=t3;
//保持无向图矩阵的对称性
if(T[t1][t2]==100) cout<<"修改成功!农场"<<t1<<"至农场"<<t2<<"距离为:None(100)\t\n";
else cout<<"修改成功!农场"<<t1<<"至农场"<<t2<<"距离为"<<T[t1-1][t2-1]<<endl<<endl;
for(j=0;j<num;j++)
{ for(k=0;k<num;k++)
{ if(k%5==0 &&k!=0)cout<<endl;
if(T[j][k]==100) cout<<j+1<<"-"<<k+1<<":None\t";
else cout<<j+1<<"-"<<k+1<<":"<<T[j][k]<<" \t";}
cout<<endl<<"------------------------------------------------------------------"<<endl;
}
}//
(4)void Display(int G[][MaxFarm],int path[MaxFarm][2],int num);//输出
{ int i,max=0;
cout<<"最小生成树是:"<<endl;
for(i=0;i<num-1;i++)
cout<<"农场"<<path[i][0]+1<<"至农场"<< path[i][1]+1<<endl;
for(i=0;i<num-1;i++)
{if(G[path[i][0]][path[i][1]]>max;max=G[path[i][0]][path[i][1]];}
cout<<"携带最大水量是:"<<' '<<max<<endl;
}
[ 源代码]
#include "iostream"
using namespace std;
#define MaxFarm 10
#define MaxWeight 100
int InitiTable(int G[][MaxFarm],int num);
int LinkJudge(int G[][MaxFarm],int num);
void find(int G[][MaxFarm],int in[],int num, int path[MaxFarm][2]);
void Display(int G[][MaxFarm],int path[MaxFarm][2],int num);
void Modify(int T[][MaxFarm],int num);
void main()
{
start: int G[MaxFarm][MaxFarm],in[MaxFarm]={0},path[MaxFarm][2];//in[]为标记,path[]为最短路径记录
int num=0,linkjug=0; /*全局*/ int ch;//选择
do{
printf("\t $ 道-路-选-择$\t\n");
printf("******************************************************************\n"); printf("\t1.创建\t");printf("2.修改路径\t"); printf("3.携带最大水量\n");
printf("\t4.退出\t\n");
printf("******************************************************************\n"); printf("请输入功能的号码:");
scanf("%d",&ch);
switch(ch)
{
case 1: num=InitiTable(G,num);
linkjug=LinkJudge(G,num);
system("pause"); system("cls"); break;
case 2: Modify(G,num);
linkjug=LinkJudge(G,num);
system("pause");system("cls"); break;
case 3: linkjug=LinkJudge(G,num);
if(!linkjug) { system("pause");system("cls");break;}
find(G,in,num,path);
Display(G,path,num);
system("pause"); system("cls"); break;
case 4: system("exit"); exit(0);
default:system("cls");
goto start;
}
}while(1);
}
int InitiTable(int G[][MaxFarm],int num)//只处理为一个指针,可同名{
int j,k,TempValue;
while(true)
{
cout<<"请输入农场的数目:"<<' ';
cin>>num;
if(num<=MaxFarm&&num>0)
break;
cout<<"错误!请重新输入."<<endl<<endl;
}
for(j=0;j<num;j++)
{
for(k=0;k<num;k++)
{
if(j==k)
G[j][k]=MaxWeight;
else if(j<k)
{
while(true)
{
cout<<"请输入农场"<<j+1<<"至农场"<<k+1<<"的距离。
如果该路不存在请输入-1:"<<endl;
cin>>TempValue;
if(TempValue>=-1&&TempValue<MaxWeight) break;
cout<<"输入无效,请重新输入。
"<<endl;
}
if(TempValue==-1)
TempValue=MaxWeight;
G[j][k]=G[k][j]=TempValue; //保持无向图矩阵的对称性
}
}
}
return num ;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void find(int G[][MaxFarm],int in[],int num, int path[MaxFarm][2])//寻找最小生成树
{
int start=0,i,j,k,v1,v2,min=MaxWeight;
while(true)
{
cout<<"请选择出发农场:"<<endl;
cin>>start;
if(start>0 &&start<=num)
break;
cout<<"输入错误!请确认后重新输入."<<endl<<endl;
}
in[start-1]=1;
for(i=0;i<num-1;i++)//这里只进行num-1次的循环
{
for(j=0;j<num;j++)
for(k=0;k<num;k++)
if(G[j][k]<min&&in[j]&&(!in[k]))
{
v1=j;
v2=k;
min=G[j][k];
}
if(!in[v2])
{
path[i][0]=v1;
path[i][1]=v2;
in[v1]=1;
in[v2]=1;
min=MaxWeight;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////
void Display(int G[][MaxFarm],int path[MaxFarm][2],int num)
{
int i,max=0;
cout<<"最小生成树是:"<<endl;
for(i=0;i<num-1;i++)
cout<<"农场"<<path[i][0]+1<<"至农场"<< path[i][1]+1<<endl;
for(i=0;i<num-1;i++)
{
if(G[path[i][0]][path[i][1]]>max)
max=G[path[i][0]][path[i][1]];
}
cout<<"携带最大水量是:"<<' '<<max<<endl;
}
/////////////////////
void Modify(int T[][MaxFarm],int num)
{
int j,k,t1,t2,t3;//t1,t2,t3是修改用的
cout<<"现有路径如下:"<<endl;
for(j=0;j<num;j++)
{ for(k=0;k<num;k++)
{ if(k%5==0 &&k!=0)cout<<endl;
if(T[j][k]==100) cout<<j+1<<"-"<<k+1<<":None\t";
else cout<<j+1<<"-"<<k+1<<":"<<T[j][k]<<" \t";}
cout<<endl<<"-----------------------------------------------------------------"<<endl;
}
cout<<"<修改>格式(不存在请输入-1):1-2:-1 (路径长度)"<<endl;
while(true)
{
scanf("%d-%d:%d",&t1,&t2,&t3);
if(t3>=-1&&t3<MaxWeight) break;
cout<<"输入无效,请重新输入。
"<<endl;
}
if(t3==-1)
T[t1-1][t2-1]=T[t2-1][t1-1]=MaxWeight;
else
T[t1-1][t2-1]=T[t2-1][t1-1]=t3;
//保持无向图矩阵的对称性
if(T[t1][t2]==100) cout<<"修改成功!农场"<<t1<<"至农场"<<t2<<"距离为:None(100)\t\n";
else cout<<"修改成功!农场"<<t1<<"至农场"<<t2<<"距离为"<<T[t1-1][t2-1]<<endl<<endl;
for(j=0;j<num;j++)
{ for(k=0;k<num;k++)
{ if(k%5==0 &&k!=0)cout<<endl;
if(T[j][k]==100) cout<<j+1<<"-"<<k+1<<":None\t";
else cout<<j+1<<"-"<<k+1<<":"<<T[j][k]<<" \t";}
cout<<endl<<"------------------------------------------------------------------"<<endl;
}
}
/////////////////////////////////////
int LinkJudge(int G[][MaxFarm],int num)
{
int linkjug,j,k;
for(j=0;j<num;j++)
{
linkjug=0;
for(k=0;k<num;k++)
if(G[j][k]<MaxWeight)
{
linkjug=1;
break;
}
if(linkjug==0)
break;
}
if(!linkjug)
{
cout<<"农场是不连通的,无法计算!"<<endl;
}
return linkjug;
}。