试题编号: 201412-4
试题名称: 最优灌溉
时间限制: 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。

问题链接:CCF201412试题。

问题描述:(参见上文)。

问题分析:这是一个最小生成树的为问题,解决的算法有Kruskal(克鲁斯卡尔)算法和Prim(普里姆) 算法。

程序说明

方法一:

用Prim算法实现,也许是算法复杂度的问题,,时间上超时了,只得了80分。希望有人能够帮助改进一下。

有关最小生成树的问题也许使用克鲁斯卡尔算法,实现上更具有优势,只需要对所有的边进行排序后处理一遍即可。

方法二:

用Kruskal算法实现。有关最小生成树的问题,使用克鲁斯卡尔算法更具有优势,只需要对所有的边进行排序后处理一遍即可。程序中使用了并查集,用来判定加入一条边后会不会产生循环。n个结点的图,其最小生成树应该是n-1条边,这个作为程序处理的结束条件。这个程序实现Kruskal算法部分的逻辑和代码都是否简洁易懂。程序中,图采用边列表的方式存储,按边的权从小到大顺序放在优先队列中,省去了排序。

参考链接:Prim算法的C语言程序。

提交后得100分的C++语言程序(方法二)如下:

/* CCF201412-4 最优灌溉 */#include <iostream>
#include <vector>
#include <queue>using namespace std;// 并查集类
class UF {
private:vector<int> v;
public:UF(int n) {for(int i=0; i<=n; i++)v.push_back(i);}int Find(int x) {for(;;) {if(v[x] != x)x = v[x];elsereturn x;}}bool Union(int x, int y) {x = Find(x);y = Find(y);if(x == y)return false;else {v[x] = y;return true;}}
};struct edge {int src, dest, cost;bool operator < (const edge& n) const {return cost > n.cost;}
};int main()
{priority_queue<edge> q;     // 优先队列,用于存储边列表edge e;// 输入数据int n, m;cin >> n >> m;for(int i=1; i<=m; i++) {cin >> e.src >> e.dest >> e.cost;q.push(e);}// Kruskal算法UF uf(n);int ans=0, count=0;for(;;) {e = q.top();q.pop();if(uf.Find(e.src) != uf.Find(e.dest)) {uf.Union(e.src, e.dest);ans += e.cost;if(++count == n -1)break;}}// 输出结果cout << ans << endl;return 0;
}/*
测试数据与结果两组:
6 10
1 2 3
1 3 1
1 4 6
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
134 4
1 2 1
2 3 4
2 4 2
3 4 3
6
*/

提交后得80分的C++语言程序(方法一)如下:

/* CCF201412-4 最优灌溉 */#include <iostream>
#include <cstring>
#include <climits>using namespace std;int main()
{int n, m, ans=0;// 输入数据cin >> n >> m;unsigned int visited[n+1], cost[n+1][n+1];memset(visited, 0, sizeof(visited));memset(cost, INT_MAX, sizeof(cost));int src, dest;for(int i=1; i<=m; i++) {cin >> src >> dest;cin >> cost[src][dest];cost[dest][src] = cost[src][dest];}// Prim算法unsigned int min;int next = 1, u, v;visited[1]=1;while(next < n) {min = INT_MAX;for(int i=1; i<=n; i++)if(visited[i] != 0)for(int j=1; j<=n; j++)if(cost[i][j] < min) {min = cost[i][j];u = i;v = j;}if(visited[u]==0 || visited[v]==0) {next++;ans += min;visited[v] = 1;}cost[u][v] = cost[v][u] = INT_MAX;}// 输出结果cout << ans << endl;return 0;
}

另外一个提交后得80分的C++程序:

/* CCF201412-4 最优灌溉 */#include <iostream>
#include <cstring>
#include <climits>using namespace std;const int TRUE = 1;
const int FALSE = 0;
const int N = 1000;unsigned int cost[N+1][N+1];
int s_set[N+1], s_count;
int vs_set[N+1], vs_count;int n, m, ans = 0;// Prim算法
void prim(int n)
{int i, j, pj;unsigned int minval;for(; vs_count > 0;) {minval = INT_MAX;for(i=1; i<=n; i++) {if(s_set[i])for(j=1; j<=n; j++)if(i!=j && vs_set[j])if(cost[i][j] < minval) {minval = cost[i][j];pj = j;}}s_set[pj] = TRUE;s_count++;vs_set[pj] = FALSE;vs_count--;ans += minval;}
}int main()
{// 变量初始化memset(cost, INT_MAX, sizeof(cost));memset(s_set, FALSE, sizeof(s_set));memset(vs_set, TRUE, sizeof(vs_set));// 输入数据cin >> n >> m;int src, dest;for(int i=1; i<=m; i++) {cin >> src >> dest;cin >> cost[src][dest];cost[dest][src] = cost[src][dest];}// Prim算法s_set[1] = TRUE;s_count = 1;vs_set[1] = FALSE;vs_count = n - 1;prim(n);// 输出结果cout << ans << endl;return 0;
}

CCF201412-4 最优灌溉(100分)相关推荐

  1. CCF201412-4 最优灌溉(解法二)(100分)【废除!!!】

    试题编号: 201412-4 试题名称: 最优灌溉 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井, ...

  2. ccf 201412-4 最优灌溉 (100分)

    问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉. 为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为&q ...

  3. CCF201409-4 最优配餐(100分)

    试题编号: 201409-4 试题名称: 最优配餐 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 栋栋最近开了一家餐饮连锁店,提供外卖服务.随着连锁店越来越多,怎么合理的给客 ...

  4. python 输入学生成绩大于 90为优_对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。以下代码如何限制成绩最高100分。...

    对学生成绩大于60分的,输出"合格".低于60分的,输出"不合格".以下代码如何限制成绩最高100分. System.out.println("输入成 ...

  5. CCF-CSP认证历年真题解(100分)

    转载: 链接出自:https://blog.csdn.net/tigerisland45/article/details/54755895 CCF-CSP认证历年真题解–python语言 CCF-CS ...

  6. 【CCF 201412-4】最优灌溉 (求最小生成树)

    CCF 201412-4 最优灌溉                                                          问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田, ...

  7. CCF201412-2 Z字形扫描(解法二)(100分)

    试题编号: 201412-2 试题名称: Z字形扫描 时间限制: 2.0s 内存限制: 256.0MB 问题描述: 问题描述 在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag ...

  8. CCF201712-1 最小差值(100分)【序列处理】

    试题编号: 201712-1 试题名称: 最小差值 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值 ...

  9. CCF201412-5 货物调度【费用流】(100分解题链接)

    问题描述 试题编号: 201412-5 试题名称: 货物调度 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 某公司要处理一个周期性的物流问题. 有n个城市,第i个城市在每周的 ...

最新文章

  1. 新手必看,17 个常见的 Python 运行时错误
  2. 树状数组模板1——单点修改区间查询
  3. elisa标准曲线怎么做_ELISA标准曲线制作
  4. openshift_红帽Openshift:入门–云中的Java EE6
  5. oracle clusterware 11g,Oracle11gR2clusterware启动顺序
  6. python除法保留两位小数_除法巧算(Ⅱ),任何整数除7~9,11的快速心算技巧,爸妈收藏...
  7. Linux设备驱动模型一 sysfs
  8. ubuntu系统VNC服务器安装配置
  9. python 安装win32com_python调用win32com.client时提示:No module named win32com.client
  10. 大数据学习——Hadoop本地模式搭建
  11. 请不要“妖魔化”外包
  12. 雷达图人格php源码,061 实例15-霍兰德人格分析雷达图
  13. 次世代游戏:科技巨头对游戏业未来的看法
  14. 一个手游外行怎样杀出万分之一创新血路(上篇)
  15. c8051f c语言编程,C8051F SPI接口读写c程序
  16. 给PS / Windows电脑添加字体
  17. 揭秘吴孟达周星驰恩怨情仇
  18. 学计算机有必要买键盘吗,别再纠结了 玩游戏必须要选专业外设
  19. python 菜鸟联盟快递查询_快递单号查询接口-极兔速递
  20. 用卷积对心音进行分类的总结1

热门文章

  1. Android中的Binder机制
  2. 移动设备响应式网站之CSS媒体查询
  3. mysql yum安装和 rpm安装_yum 和 rpm安装mysql彻底删除
  4. 用python画大白圣诞快乐呦
  5. Spark中DataFrame 基本操作函数
  6. 详解:Hive中的NULL的处理、优点、使用情况(注意)
  7. c语言倒序输出单词_洛谷 || 单词覆盖还原(C语言)
  8. 天线下倾角示意图_天线下倾角地计算方法
  9. 编译原理课程作业-Cminus语言的词法及语法分析器实现
  10. Python数据结构与算法笔记(七):数据结构——队列,链表和哈希表