1001 ProblemA
2016-06-12 20:21
274 查看
题意:
有N个村庄 编号是从1到N,需要把他们连通起来,如果1到2和2到3有路,1到3也是连通的,给出每个村庄之间的距离,求修路最少要修多长才能使所有村庄连通。
思路:
这是一个最小生成树的问题,用Prim算法,选定一个点把与这个点相关的最小的边连上,然后再选与这两个点相关的最小的边连上,以此类推,直到全连上。
我本来用并查集做的,按边排序,把最小的边连上,总是超时,就又换了种思路。
有N个村庄 编号是从1到N,需要把他们连通起来,如果1到2和2到3有路,1到3也是连通的,给出每个村庄之间的距离,求修路最少要修多长才能使所有村庄连通。
思路:
这是一个最小生成树的问题,用Prim算法,选定一个点把与这个点相关的最小的边连上,然后再选与这两个点相关的最小的边连上,以此类推,直到全连上。
我本来用并查集做的,按边排序,把最小的边连上,总是超时,就又换了种思路。
#include<iostream> #include<fstream> #include<cstdio> #include<cstring> using namespace std; const int N = 110; const int INF = 0x3f3f3f3f; int n, ans; int map , dis , vis ; void Prim() { int i; for (i = 1;i <= n;i++) { dis[i] = map[1][i]; vis[i] = 0; } vis[1] = 1; int j, k, tmp; for (i = 1;i <= n;i++) { tmp = INF; for (j = 1;j <= n;j++) if (!vis[j] && tmp>dis[j]) { k = j; tmp = dis[j]; } if (tmp == INF) break; vis[k] = 1; ans += dis[k]; for (j = 1;j <= n;j++) if (!vis[j] && dis[j]>map[k][j]) dis[j] = map[k][j]; } } int main() { fstream cin("E:/C++/IN/aaa.txt"); while (cin>>n) { for (int i = 1;i <= n;i++) for (int j = 1;j <= n;j++) cin>>map[i][j]; int q, a, b; cin>>q; while (q--) { cin >> a >> b; map[a][b] = map[b][a] = 0; } ans = 0; Prim(); cout << ans << endl; } return 0; }
相关文章推荐
- 计算机组成原理运算器的编程实现
- 构建之法阅读笔记06
- God Chang's interview——异或
- 大、小根堆
- 用Kibana和logstash快速搭建实时日志查询、收集与分析系统
- 范型程序设计——洗牌
- codevs 2241 排序二叉树
- ViewPager源码分析(1):onMeasure、onLayout
- 【GDOI2014模拟】网格
- Error connecting to database [No such file or directory]
- 对‘pthread_create’未定义的引用 对‘pthread_join’未定义的引用
- 一步步写bitbake简单的helloworld expamle(2)
- Java集合细节:subList的缺陷
- ThreadPoolExecutor详解
- mySQL锁表
- halcon ocr - bottle 源码分析
- SQLsever语句建立信息表
- Oracle EBS 公司间往来的解决方案
- Labview实现简单知乎日报客户端
- php中的&&与&的区别