最小生成树之安慰奶牛
来源:互联网 发布:编写sql语句的工具 编辑:程序博客网 时间:2024/05/23 01:58
代码:有个问题就是数组开的太大了超出运行的内存限制。
#include<iostream>
#include<string.h>#include<algorithm>
using namespace std;
int cost[10005];
#define MIN 0x7fffffff
typedef struct
{
int connect[10005][10005];
int n;
}Mat;
Mat g;
int prim(int start)
{
int lowcost[10005],m,record,closest[10005];
for(int i=1;i<=g.n;i++)
{
lowcost[i]=g.connect[start][i];
closest[i]=start;
}
for(int j=2;j<=g.n;j++)//找出n-1个点
{
m=MIN;
for(int k=1;k<=g.n;k++)
{
if(lowcost[k]!=0&&lowcost[k]!=-1&&lowcost[k]<m)
{
m=lowcost[k];
record=k;
}
}
cout<<"当前选择点为:"<<record<<endl;
lowcost[record]=0;
for(int u=1;u<=g.n;u++)
{
if(lowcost[u]&&g.connect[record][u]!=0&&(lowcost[u]==-1||lowcost[u]>g.connect[record][u]&&g.connect[record][u]!=-1))
{
cout<<"原值为"<<lowcost[u]<<" "<<"现值为"<<g.connect[record][u]<<endl;
lowcost[u]=g.connect[record][u];
closest[u]=record;//记录前驱
}
}
}
int sum1=0;
for(int y=1;y<=g.n;y++)
{
int s1=closest[y];
int o1=y;
sum1+=g.connect[s1][o1];
}
return sum1;
}
int main()
{
int n,p,max1=0x80000000,record,data=0x7fffffff;
cin>>n>>p;
for(int t=1;t<=n;t++)
{
cin>>cost[t];
if(cost[t]<data)
{
data=cost[t];
record=t;
}
}
memset(g.connect,-1,sizeof(g.connect));
for(int z=1;z<=p;z++)
{
int s,e,c;
cin>>s>>e>>c;
if(max1<max(s,e))
{
max1=max(s,e);
}
if(g.connect[s][e]==-1||g.connect[e][s]==-1)
{
g.connect[s][e]=g.connect[e][s]=2*c+cost[e]+cost[s];
}
else
{
g.connect[e][s]=g.connect[s][e]=min(2*c+cost[e]+cost[s],g.connect[s][e]);
}
}
for(int l=1;l<=max1;l++)
{
g.connect[l][l]=0;
}
g.n=max1;
cout<<"图表为:"<<endl;
for(int q=1;q<=max1;q++)
{
for(int f=1;f<=max1;f++)
{
cout<<g.connect[q][f]<<" ";
}
cout<<endl;
}
cout<<"\n\n\n";
cout<<prim(1)+cost[record];
return 0;
}
优化1:vector动态偷空间,因为静态数组是无法更改大小的,所以必须在声明的时候开的足够大,这样可能连基本样例都运行不了,因此用vector动态开一个二维数组即可。
include<iostream>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
int cost[10005];
#define MIN 0x7fffffff
typedef struct
{
vector<vector<int> > connect;
int n;
}Mat;
Mat g;
int prim(int start)
{
int lowcost[10005],m,record,closest[10005];
for(int i=1;i<=g.n;i++)
{
lowcost[i]=g.connect[start][i];
closest[i]=start;
}
for(int j=2;j<=g.n;j++)//找出n-1个点
{
m=MIN;
for(int k=1;k<=g.n;k++)
{
if(lowcost[k]!=0&&lowcost[k]!=-1&&lowcost[k]<m)
{
m=lowcost[k];
record=k;
}
}
cout<<"当前选择点为:"<<record<<endl;
lowcost[record]=0;
for(int u=1;u<=g.n;u++)
{
if(lowcost[u]&&g.connect[record][u]!=0&&(lowcost[u]==-1||lowcost[u]>g.connect[record][u]&&g.connect[record][u]!=-1))
{
cout<<"原值为"<<lowcost[u]<<" "<<"现值为"<<g.connect[record][u]<<endl;
lowcost[u]=g.connect[record][u];
closest[u]=record;//记录前驱
}
}
}
int sum1=0;
for(int y=1;y<=g.n;y++)
{
int s1=closest[y];
int o1=y;
sum1+=g.connect[s1][o1];
}
return sum1;
}
int main()
{
int n,p,max1=0x80000000,record,data=0x7fffffff;
cin>>n>>p;
for(int b=0;b<=n;b++)
{
vector<int> v(n+1,-1);
g.connect.push_back(v);
}
for(int t=1;t<=n;t++)
{
cin>>cost[t];
if(cost[t]<data)
{
data=cost[t];
record=t;
}
}
for(int z=1;z<=p;z++)
{
int s,e,c;
cin>>s>>e>>c;
if(max1<max(s,e))
{
max1=max(s,e);
}
if(g.connect[s][e]==-1||g.connect[e][s]==-1)
{
g.connect[s][e]=g.connect[e][s]=2*c+cost[e]+cost[s];
}
else
{
g.connect[e][s]=g.connect[s][e]=min(2*c+cost[e]+cost[s],g.connect[s][e]);
}
}
for(int l=1;l<=max1;l++)
{
g.connect[l][l]=0;
}
g.n=max1;
cout<<"图表为:"<<endl;
for(int q=1;q<=max1;q++)
{
for(int f=1;f<=max1;f++)
{
cout<<g.connect[q][f]<<" ";
}
cout<<endl;
}
cout<<"\n\n\n";
cout<<prim(1)+cost[record];
return 0;
}
初步测试可以偷到一半的分,好了,继续优化。
优化2:因为这种存图的矩阵实际上是对称的,所以connect[s][j]==connect[j][s],所以我们只需要规定s>=j也就是下三角矩阵部分就行,对于这个部分,完全可以采用一维存储。存储公式为connect[s][j]==data[(s-1)*s/2+j]
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int cost[10005];
#define MIN 0x7fffffff
typedef struct
{
int connect[26000000];
int n;
}Mat;
Mat g;
int prim(int start)
{
int lowcost[10005],m,record,closest[10005];
for(int i=1;i<=g.n;i++)
{
int s1=max(start,i);
int e1=min(start,i);
int tran=(s1-1)*s1/2+e1;
lowcost[i]=g.connect[tran];
closest[i]=start;
}
for(int j=2;j<=g.n;j++)//找出n-1个点
{
m=MIN;
for(int k=1;k<=g.n;k++)
{
if(lowcost[k]!=0&&lowcost[k]!=-1&&lowcost[k]<m)
{
m=lowcost[k];
record=k;
}
}
lowcost[record]=0;
for(int u=1;u<=g.n;u++)
{
int s1=max(record,u);
int e1=min(record,u);
int tran=(s1-1)*s1/2+e1;
if(lowcost[u]&&g.connect[tran]!=0&&(lowcost[u]==-1||lowcost[u]>g.connect[tran]&&g.connect[tran]!=-1))
{
lowcost[u]=g.connect[tran];
closest[u]=record;//记录前驱
}
}
}
int sum1=0;
for(int y=1;y<=g.n;y++)
{
int s1=max(closest[y],y);
int o1=min(closest[y],y);
sum1+=g.connect[s1*(s1-1)/2+o1];
}
return sum1;
}
int main()
{
int n,p,max1=0x80000000,record,data=0x7fffffff;
cin>>n>>p;
for(int t=1;t<=n;t++)
{
cin>>cost[t];
if(cost[t]<data)
{
data=cost[t];
record=t;
}
}
memset(g.connect,-1,sizeof(g.connect));
for(int z=1;z<=p;z++)
{
int s,e,c;
cin>>s>>e>>c;
if(max1<max(s,e))//(s为行 e为列)
{
max1=max(s,e);
}
int s1=max(s,e);
int e1=min(s,e);
int tran=(s1-1)*s1/2+e1;
if(g.connect[tran]==-1)
{
g.connect[tran]=2*c+cost[e1]+cost[s1];
}
else
{
g.connect[tran]=min(2*c+cost[e1]+cost[s1],g.connect[tran]);
}
}
for(int l=1;l<=max1;l++)
{
g.connect[l*(l-1)/2+l]=0;
}
g.n=max1;
cout<<prim(1)+cost[record];
return 0;
}
优化3:三元组(即定义一个结构体node,含有成员row,col,value,但是在寻找的时候还是比较麻烦的)
- 最小生成树之安慰奶牛
- 安慰奶牛 最小生成树
- 安慰奶牛【最小生成树】
- [Usaco2008Nov]安慰奶牛cheer 最小生成树
- 蓝桥杯 安慰奶牛(最小生成树)
- 蓝桥杯 - 安慰奶牛 (最小生成树)
- 算法训练 安慰奶牛 最小生成树
- 安慰奶牛 (Kruskal) (最小生成树)
- 安慰奶牛(最小生成树)
- 算法训练 安慰奶牛 最小生成树
- 蓝桥杯 算法训练 安慰奶牛 最小生成树
- 蓝桥杯-安慰奶牛(最小生成树kruskal)
- 算法训练 安慰奶牛(最小生成树)
- 【BZOJ1232】[Usaco2008Nov]安慰奶牛cheer【最小生成树】
- BZOJ1232: [Usaco2008Nov]安慰奶牛cheer 最小生成树 Kruskal
- BZOJ 1232: [Usaco2008Nov]安慰奶牛cheer Kruskal最小生成树
- 蓝桥杯--算法练习:安慰奶牛(kruskal最小生成树)
- 算法训练 安慰奶牛 (Kruscal算法求最小生成树)
- LintCode-【容易】9.Fizz Buzz问题
- 树莓派3B+ 安装计算机视觉库(OpenCV_2.4.9官方源)
- Java for Web学习笔记(九三):消息和集群(8)RabbitMQ和消息模式(中)
- POJ1625-Censored!
- VINS mono 系统学习 五
- 最小生成树之安慰奶牛
- 带你彻底搞定希尔排序是个什么情况
- 声明和定义的区别
- 分治法计算乘幂
- 习题6.2(2)计算1*2*3+3*4*5+...+99*100*101的值
- LeetCode.720 Longest Word in Dictionary
- 讲一下Markdown
- A Survey on Techniques in NLP--阅读笔记
- softmax_cross_entropy softmax交叉熵 tensorflow numpy