码迷,mamicode.com
首页 > 其他好文 > 详细

CCF真题之最优灌溉

时间:2015-12-08 22:01:48      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:

201412-4
问题描述
  雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。   为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中转站”,利用水渠连接不同的麦田,这样只要一片麦田能被灌溉,则与其连接的麦田也能被灌溉。   现在雷雷知道哪些麦田之间可以建设水渠和建设每个水渠所需要的费用(注意不是所有麦田之间都可以建立水渠)。请问灌溉所有麦田最少需要多少费用来修建水渠。
输入格式
  输入的第一行包含两个正整数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。
 
源代码:

 

#include<bits/stdc++.h> //该头文件包含C++所有头文件(编程中显得非常方便,很省时间)

//#include <vector> //若无以上头文件,则需要添加下面这两个头文件才不会报错

//#include <iostream>

using namespace std;

const int maxn=1007;

const int inf=10001;    

int n,m;   struct node   {      

int to,cost;  

};  

bool vis[maxn];

int d[maxn];  

vector<node> G[maxn];  

void init()  {     

for(int i=0;i<maxn;i++)      {         

G[i].clear();     

}  

}

//最小生成数prim,CCF中可以直接调用

 int prim()  {     

int ans=0;     

for(int i=1;i<maxn;i++)      {         

d[i]=inf;         

vis[i]=0;     

}     

d[1]=0;     

while(1){         

int v=-1;         

for(int i=1;i<=n;i++)          {             

if(!vis[i]&&(v==-1||d[i]<d[v])) v=i;         

}         

if(v==-1) break;         

vis[v]=1;         

ans+=d[v];         

for(int i=0;i<G[v].size();i++)          {               

if(vis[G[v][i].to]) continue;               

d[G[v][i].to]=min(d[G[v][i].to],G[v][i].cost);         

}     

}     

return ans;  

}  

int main()  {                   

int a,b,c; node n1;        

while(cin>>n>>m){         

init();        

for(int i=0;i<m;i++)          {            

cin>>a>>b>>c;             

n1.to=b;n1.cost=c;             

G[a].push_back(n1);             

n1.to=a;             

G[b].push_back(n1);         

}         

int ans=prim();         

cout<<ans<<endl;  

//用于检测每个节点的邻接节点以及权值是否正确      

/*for(int i=1;i<=n;i++)         {      

for(int j=0;j<G[i].size();j++)      

cout<<G[i][j].to<<" "<<G[i][j].cost<<endl;               

}*/        }   

 }

 

若CCF中再次考到最小生成树,但是输入方式为:

第一行为:给定n个点,表示当前有多少块麦田

接下来n行表示:

每块麦田之间是否相连接以及相应的权值

如该题输入方式可改为:

4

0 1 0 0

1 0 4 2

0 4 0 3

0 2 3 0

输出结果仍为6
 
 
main函数中代码修改如下:
int main()
{
  int a;
   node n1;
        while(cin>>n){
         init();
         for(int i=0;i<n;i++)
         for(int j=0;j<n;j++)
         {
             cin>>a;
             if(a!=0)
             {
             n1.to=j+1;n1.cost=a;
             G[i+1].push_back(n1);
             n1.to=i+1;
             G[j+1].push_back(n1);
             }
            
         }
         int ans=prim();
         cout<<ans<<endl;

       //用于检测每个节点的邻接节点以及权值是否正确      

       /*for(int i=1;i<=n;i++)         {      

          for(int j=0;j<G[i].size();j++)      

          cout<<G[i][j].to<<" "<<G[i][j].cost<<endl;               

      }*/        }   


       }
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 

CCF真题之最优灌溉

标签:

原文地址:http://www.cnblogs.com/lchzls/p/5030814.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!