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 }        
View Code

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)

nyoj 1239 引水project (河南省第八届acm程序设计大赛)

最优灌溉_最小生成树Kruskal

1863 畅通工程-并查集最小生成树

还是畅通工程——最小生成树模板题