您的位置:首页 > 其它

【CCF】最优灌溉

2015-09-03 23:41 204 查看
试题名称: 最优灌溉

时间限制: 1.0s

内存限制: 256.0MB

问题描述:

问题描述

  雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。

  为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中转站”,利用水渠连接不同的麦田,这样只要一片麦田能被灌溉,则与其连接的麦田也能被灌溉。

  现在雷雷知道哪些麦田之间可以建设水渠和建设每个水渠所需要的费用(注意不是所有麦田之间都可以建立水渠)。请问灌溉所有麦田最少需要多少费用来修建水渠。

输入格式

  输入的第一行包含两个正整数n, m,分别表示麦田的片数和雷雷可以建立的水渠的数量。麦田使用1, 2, 3, ……依次标号。

  接下来m行,每行包含三个整数ai, bi, ci,表示第ai片麦田与第bi片麦田之间可以建立一条水渠,所需要的费用为ci。

输出格式

  输出一行,包含一个整数,表示灌溉所有麦田所需要的最小费用。

样例输入

4 4

1 2 1

2 3 4

2 4 2

3 4 3

样例输出

6

样例说明

  建立以下三条水渠:麦田1与麦田2、麦田2与麦田4、麦田4与麦田3。

评测用例规模与约定

  前20%的评测用例满足:n≤5。

  前40%的评测用例满足:n≤20。

  前60%的评测用例满足:n≤100。

  所有评测用例都满足:1≤n≤1000,1≤m≤100,000,1≤ci≤10,000。

该题目用最小生成树的数据结构即可解决。

这次提交出现两个错误:

1. 编译错误

for(int i = 0;;)这样的在VC6.0可以编译成功,但是在2010却编译失败了

2. 运行错误 && 答案错误

权值可以是0(题目并没有说明)。所以要用-1来表示缺省值。用0的话会导致这两个错误。

#include<iostream>
using namespace std;

int lc = 0;

class Closedge{
public:
int adjvex;
int lowcost;
};

int minmum(Closedge* closedge,int size){
int temp=closedge[0].lowcost,k=0,i=0;
while(temp==-1 && i<size){
temp=closedge[i+1].lowcost;
i++;
k=i;
}//while
for(;++i<size;){
if(closedge[i].lowcost!=-1 && temp>closedge[i].lowcost){
temp=closedge[i].lowcost;
k=i;
}//if
}//for
return k;
}//minmum

int main(){
int m,n,x,y,w,i,j;

int index = 1;
cin>>m>>n;

int **Matrix=new int*[m];
for(i=-1;++i<m;){
Matrix[i]=new int[m];
for(j=-1;++j<m;){
Matrix[i][j]=9999;
//cout<<Matrix[i][j]<<" ";
}//for
//cout<<endl;
}//for

while(n--){
cin>>x>>y>>w;
Matrix[x-1][y-1] = w;
Matrix[y-1][x-1] = w;
}
/*  for(i=-1;++i<m;){
for(j=-1;++j<m;){
cout<<Matrix[i][j]<<" ";
}//for
cout<<endl;
}//for*/
//用k来表示当前访问的结点
int k=index;
//Closedge{adjvex,lowcost}  adjvex表示当前为adjvex这个编号的结点指向以下标+1为编号的结点所需要的权值比其它边都要小
//lowcost记录这个权值最小的边
Closedge *closedge=new Closedge[m];
//初始化closedge数组,把index(即k)这个编号的结点指向其它Size-1个结点的权值储存进lowcost来 adjvex全部赋值为index
//如果index与某个结点不相通的话直接赋值为-1,在以后的判断中会把-1排除掉
for(i=-1;++i<m;){
closedge[i].lowcost=-1;
closedge[i].adjvex=-1;
if(i!=k-1){
closedge[i].adjvex=k;
closedge[i].lowcost=Matrix[k-1][i];
}//if
}//for
//起点已经访问过了,直接赋值为-1
closedge[k-1].lowcost=-1;
//开始遍历结点之旅
for(i=0;++i<m;){
k=minmum(closedge,m);  //minmum函数是获取closedge数组中lowcost最小的那个结点下标
//      cout<<"k="<<k<<" ";
lc += closedge[k].lowcost;
//     cout<<closedge[k].adjvex-1<<"-"<<k<<endl;   //输出最小的那条边
index=k+1;                     //访问的结点改成查找到的结点
closedge[k].lowcost=-1;         //设置已找到的结点为已访问
//对找到的结点进行对其它未访问的结点的遍历,由于已访问的结点lowcost已被标为-1,所以if判断语句无法通过
for(int j=-1;++j<m;)
{
if(Matrix[k][j]<closedge[j].lowcost){  //如果这个结点访问某个结点的权值比上一个结点访问同一个结点的权值要小
//更改成更小的权值
closedge[j].adjvex=k+1;
closedge[j].lowcost=Matrix[k][j];
}//if
//  cout<<closedge[j].adjvex<<" "<<closedge[j].lowcost<<endl;
}//for
}//for
cout<<lc<<endl;
for(i=-1;++i<m;){
delete[]Matrix[i];
}//for
delete[]Matrix;
delete[]closedge;
return 0;
}//main
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: