Nyoj 引水工程(最小生成树)
Posted C-DmLy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nyoj 引水工程(最小生成树)相关的知识,希望对你有一定的参考价值。
描述
南水北调工程是优化水资源配置、促进区域协调发展的基础性工程,是新中国成立以来投资额最大、涉及面最广的战略性工程,事关中华民族长远发展。“南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家战略性工程。就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区。我国南涝北旱,南水北调工程通过跨流域的水资源合理配置,促进南北方经济、社会与人口、资源、环境的协调发展。
整个工程分东线、中线、西线三条调水线。东线工程位于东部,因地势低需抽水北送至华北地区。中线工程从汉水与其最大支流丹江交汇处的丹江口水库引水,自流供水给黄淮海平原大部分地区,20多座大中城市;西线工程在青藏高原上,由长江上游向黄河上游补水。
现在有N个区域需要建设水资源工程,它们可以自建水库解决缺水问题,也可以从已有水源的地区建立管道引水过来。当然,这些建设都需要大量投资。
你能不能给出一个优化水资源配置方案,在保证每个区域都能用上水的前提下,使得整个引水工程费用最低。
- 输入
- 第一行: K 表示有多少组测试数据。
接下来对每组测试数据:
第1行: N 表示有N个区域( 1<=N<=300 )
第2 行: W1 W2 …. WN Wi表示第i个区域自建水库需要的费用
再有N行: Pi1 Pi2 …. Pin Pij表示建立第i个区域与第j个区域引水管道的费用 - 输出
- 对于每组测试数据,输出占一行,即建立整个引水工程的最小费用。
- 样例输入
-
1 5 5 4 4 3 6 0 2 2 2 2 2 0 3 3 3 2 3 0 4 5 2 3 4 0 1 2 3 5 1 0
- 样例输出
-
10
- 来源
- 第八届河南省程序设计大赛
- 上传者
- hnu_acm
题解: 找到建立水库的最小值,以此建立最小生成树.......蒟蒻啊 ....自己刚开始的思路想错了.....
WA代码:
1 #include <vector> 2 #include <map> 3 #include <set> 4 #include <algorithm> 5 #include <iostream> 6 #include <cstdio> 7 #include <cmath> 8 #include <cstdlib> 9 #include <string> 10 #include <cstring> 11 #include <queue> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 #define MAX 100010 15 16 int n,ans,minn; 17 int quyu[333],vis[333],dis[333]; 18 int mp[333][333]; 19 20 void prim() 21 { 22 memset(vis,0,sizeof(vis)); 23 memset(dis,INF,sizeof(dis)); 24 dis[1]=0; 25 ans=0; 26 dis[0]=INF; 27 while(true){ 28 int m=0; 29 for(int i=1; i<=n; i++){ 30 if(!vis[i] && dis[i]<dis[m]) 31 m=i; 32 } 33 if(m==0) 34 break; 35 vis[m]=1; 36 ans+=dis[m]; 37 for(int i=1; i<=n; i++) 38 dis[i]=min(dis[i],mp[m][i]); 39 } 40 } 41 42 void init() 43 { 44 memset(mp,INF,sizeof(mp)); 45 memset(quyu,0,sizeof(quyu)); 46 minn=INF; 47 } 48 49 int main() 50 { 51 int t; 52 scanf("%d",&t); 53 while(t--){ 54 init(); 55 scanf("%d",&n); 56 for(int i=0; i<n; i++){ 57 scanf("%d",&quyu[i]); 58 if(minn>quyu[i]) 59 minn=quyu[i]; 60 } 61 for(int i=1; i<=n; i++) 62 for(int j=1; j<=n; j++){ 63 scanf("%d",&mp[i][j]); 64 } 65 prim(); 66 printf("%d\n",ans+minn); 67 } 68 }
AC代码:
1 #include <vector> 2 #include <map> 3 #include <set> 4 #include <algorithm> 5 #include <iostream> 6 #include <cstdio> 7 #include <cmath> 8 #include <cstdlib> 9 #include <string> 10 #include <cstring> 11 #include <queue> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 #define MAX 100010 15 16 int n,ans,minn; 17 int quyu[333],vis[333],dis[333]; 18 int mp[333][333]; 19 20 void prim() 21 { 22 memset(vis,0,sizeof(vis)); 23 memset(dis,INF,sizeof(dis)); 24 for(int i=0;i<=n;i++) 25 dis[i]=mp[0][i]; 26 ans=0; 27 //dis[0]=INF; 28 while(true){ 29 int m=0; 30 for(int i=1; i<=n; i++){ 31 if(!vis[i] && dis[i]<dis[m]) 32 m=i; 33 } 34 if(m==0) 35 break; 36 vis[m]=1; 37 ans+=dis[m]; 38 for(int i=1; i<=n; i++) 39 dis[i]=min(dis[i],mp[m][i]); 40 } 41 } 42 43 void init() 44 { 45 memset(mp,INF,sizeof(mp)); 46 memset(quyu,0,sizeof(quyu)); 47 minn=INF; 48 } 49 50 int main() 51 { 52 int t; 53 scanf("%d",&t); 54 while(t--){ 55 init(); 56 scanf("%d",&n); 57 for(int i=1; i<=n; i++){ 58 scanf("%d",&mp[0][i]); 59 } 60 for(int i=1; i<=n; i++) 61 for(int j=1; j<=n; j++){ 62 scanf("%d",&mp[i][j]); 63 } 64 prim(); 65 printf("%d\n",ans); 66 } 67 }
以上是关于Nyoj 引水工程(最小生成树)的主要内容,如果未能解决你的问题,请参考以下文章
nyoj 1239 引水工程 (河南省第八届acm程序设计大赛)
BZOJ_1601_[Usaco2008_Oct]_灌水_(最小生成树_Kruskal)