此次实验;
题目一:
练习使用贪心算法求解“会场安排”问题;
题目二:
练习使用Prim算法求解“最小生成树”问题。
实验内容:
会场安排问题:假设在足够多的会场里安排一批活动(N个活动),每个活动事先给定活动的开始时间和结束时间,试用贪心算法求出最少需要多少会场,并求出每个活动安排在第几个会场;
例如:5个活动的开始时间和结束时间和会场安排如下
活动 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
开始时间 | 1 | 12 | 25 | 27 | 36 |
结束时间 | 23 | 28 | 35 | 80 | 50 |
会场安排 | 一 | 二 | 一 | 三 | 一 |
Prim算法求解“最小生成树”问题
题目一代码:
#include<bits/stdc++.h>
using namespace std;
#define M 100
int array1[M];
int array2[M];
void arange(int array1[M],int array2[M],int n){
int array3[M];
memset(array3,0,sizeof(array3));//作用是标记该活动是否已经找到会场。
int maxnum=0;//需要的会场的个数
int t=0;//记录当前活动的序号
int s=0;//每个会场的活动个数
int counts=0;//记录总共标记的活动数
while(true){
s=0;//开始新的一个会场的活动
// t=0;
for(int i=0;i<n;i++){
if(array3[i]==1) continue;//已标记的活动直接跳过
//寻找下一个相容的活动,找到就break
for(int j=i;j<n;j++){
s++;//遍历活动,加一 每个会场的活动个数
//如果是第一个没归入会场的活动标记下来,归入新会场的第一个活动
if(s==1){
array3[i]=1;
if(t==0){
printf("活动1加入第%d个会场\n",maxnum+1);
}
else
printf("活动%d加入第%d个会场\n",t,maxnum+1);
counts++;//已经加入活动的数目加一
}
//得到下一个相容的活动。,归入新的会场,结束循环
if(array2[i]<array1[j] && array3[j]==0){
array3[j]=1;
t=j;//更新归入的活动的坐标,下次从这个活动向后找
printf("第%d个活动安排在第%d个会场\n",t+1,maxnum+1);
counts++;//已经加入会场的数目加一
break;
}
}
}
maxnum++;//会场的数目加一
if(counts==n){//所有活动处理完,结束
break;
}
}
cout << "需要会场数:";
cout << maxnum;
}
int main()
{
int n;
cout<< "请输入会场个数:\n";
cin >> n;
printf("起点时间 终止时间\n");
memset(array1,0,sizeof(array1));//用户输入的活动的起始点
memset(array2,0,sizeof(array2));//用户输入的活动的结束时间
for(int i=0;i<n;i++){
cin >> array1[i] >> array2[i];
}
int array3[n];
int array4[n];
memset(array3,0,sizeof(array3));//存储排序后的活动的起始点
memset(array4,0,sizeof(array4));//存储排序后的活动的终止时间点
for(int i=0;i<n;i++){//复制一下起始时间,
array3[i]=array1[i];
}
sort(array3,array3+n);//所有的活动根据起始时间进行排序用array3和array4进行存储
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
{
if(array1[j]==array3[i]){
array4[i]=array2[j];
}
}
}
arange(array3,array4,n);
}
嘿嘿~代码还是有毛病,不过我也懒得改了就这样了吧。。。
题目二代码:
#include<stdio.h>
#include <stdlib.h>
#define MAX 100
#define Maxcost 0x7fffffff
int graph[MAX][MAX];
void prim(int graph[][MAX],int n){
int i,j,k;
int lowcost[MAX];
int closeset[MAX],used[MAX];
int mmin;
int sumcost=0;
printf("最小生成树的边为:\n");
for(i=1;i<=n;i++){
lowcost[i]=graph[1][i];
//printf("lowcost[%d]=%d\n",i,lowcost[i]);
closeset[i]=1;
used[i]=0;
}
used[1]=1;
for(i=2;i<=n;i++){
j=1;
mmin=Maxcost;
for(k=2;k<=n;k++){
if((!used[k])&&(lowcost[k]<mmin)){
mmin=lowcost[k];
j=k;
}
}
printf("%d %d\n",j,closeset[j]);
sumcost+=graph[j][closeset[j]];
used[j]=1;
for(k=2;k<=n;k++){
if(!used[k]&&(graph[j][k]<lowcost[k])){
lowcost[k]=graph[j][k];
closeset[k]=j;
}
//printf("lowcost[%d]=%d\n",k,lowcost[k]);
}
}
printf("最小造价为:%d\n",sumcost);
}
int main(){
FILE *fr;
int s,e;
int i,j,weight;
fr=fopen("input.txt","r");
if(!fr){
printf("openning file failed!\n");
exit(1);
}
fscanf(fr,"%d %d",&s,&e);
printf("共%d个点 %d条边\n",s,e);
for(i=0; i<=e; i++)
for(j=0; j<=e; j++)
graph[i][j] = Maxcost;
while(e--){
fscanf(fr,"%d%d%d",&i,&j,&weight);
printf("%d %d %d\n",i,j,weight);
graph[i][j]=weight;
graph[j][i]=weight;
}
prim(graph,s);
return 0;
}
输入数据的txt文件内容:
运行结果图;
完啦~