题意:
有n个村庄,从1到n,你应该修建一些道路,这样每两个村庄就可以互相连接。我们说两个村庄A和B是相连的,如果并且仅当在A和B之间有一条道路,或者存在一个村庄C,使得A和C之间有一条道路,并且C和B是相连的。

Input:
村庄个数n
以矩阵形式输入村庄间的距离,点(i,j)表示村庄 i -> j 的距离
输入q
接下来q行,每行两个数字代表这两个村庄是相同的

Output:
输出将所有村庄连接起来的最小耗费。

Prim需要注意:

  • 图需要初始化,且在main里初始化
  • 输入数据时候需要注意可能存在多重边的情况,取最短边的值保存(但是本题没有这种情况。
  • 处理q个数据的时候:
    Prim算法解决时,将二维数组Map[a][b]设置为0,表示两个村庄相连
    Kruskal算法解决时,使用find函数,将这两个村庄归为同一类。

第一次写的Prim:

#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 150;int n, q;
int Map[maxn][maxn];
int dis[maxn];
int vis[maxn];int prim()
{//initializememset(vis, 0, sizeof(vis));/*for (int i = 0; i <= n; i++)//图的初始化不可以放在prim函数里,之后输入的数据会被 调用这个函数时覆盖成初始化数据!!!for (int j = 0; j <= n; j++)Map[i][j] = i == j ? 0 : INF;*/for (int i = 1; i <= n; i++)dis[i] = Map[1][i];//vis[1] = 1;for (int i = 1; i <= n; i++){int Min = INF, min_index = -1;for (int j = 1; j <= n; j++){if (dis[j] < Min && !vis[j]){Min = dis[j];min_index = j;}}if (min_index != -1)vis[min_index] = 1;for (int j = 1; j <= n; j++){if (dis[j] > Map[min_index][j] && !vis[j])dis[j] = Map[min_index][j];}}int ans = 0;for (int i = 1; i <= n; i++)ans += dis[i];return ans;
}int main()
{for (int i = 0; i <= n; i++)for (int j = 0; j <= n; j++)Map[i][j] = i == j ? 0 : INF;cin >> n;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)cin >> Map[i][j];cin >> q;for (int i = 1; i <= q; i++){int a, b;cin >> a >> b;Map[a][b] = Map[b][a] = 0;}cout << prim() << endl;return 0;
}

第二次写的Prim

#pragma warning(disable:4996)
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int maxn = 1115;
const int INF = 9999999;int dis[maxn];
int vis[maxn];
int n;
int a[maxn][maxn];void prim(int s)
{for (int i = 1; i <= n; i++)dis[i] = a[s][i];//vis[s] = 1;for (int i = 1; i <= n; i++){int Min = INF, min_index = -1;for (int j = 1; j <= n; j++){if (Min > dis[j] && !vis[j]){Min = dis[j];min_index = j;}}if (min_index != -1)vis[min_index] = 1;for (int j = 1; j <= n; j++){if (dis[j] > a[min_index][j] && !vis[j])dis[j] = a[min_index][j];}}}int main()
{cin >> n;memset(dis, 0, sizeof(dis));memset(vis, 0, sizeof(vis));for (int i = 0; i <= n; i++)for (int j = 0; j <= n; j++)a[i][j] = i == j ? 0 : INF;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)cin >> a[i][j];int m; cin >> m;for (int i = 0; i < m; i++){int u, v;cin >> u >> v;a[v][u] = a[u][v] = 0;}/*for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++)cout << a[i][j] << " ";cout << endl;}*/prim(1);int ans = 0;for (int i = 1; i <= n; i++)ans += dis[i];//cout << dis[i] << " ";cout << ans << endl;return 0;
}

第一次写的Kruskal:

#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int maxn = 99999;struct edge
{int u, v, w;
};
int n, q;
edge a[maxn];
int par[maxn];
bool cmp(edge a, edge b)
{return a.w < b.w;
}
void ini()
{for (int i = 0; i <= n; i++)par[i] = i;
}
int find(int x)
{if (par[x] == x)return par[x];return par[x] = find(par[x]);
}int main()
{cin >> n;ini();//先输入n啊!!!不然初始化个鬼啊,这个智障错误找了半天int t = 0;//统计 非0边的条数,后面会用到for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){int w; cin >> w;//不可以cin>>a[t].w;!!!if (i != j){a[t].u = i;a[t].v = j;a[t].w = w;t++;}}}sort(a, a + t, cmp);cin >> q;while (q--){int a, b;cin >> a >> b;int fa = find(a);int fb = find(b);par[fb] = fa;}int ans = 0;for (int i = 0; i < t; i++){int fa = find(a[i].u);int fb = find(a[i].v);if (fa != fb){par[fb] = fa;ans += a[i].w;}}cout << ans << endl;return 0;
}

第二次写的Kruskal

//Kruskal:
#pragma warning(disable:4996)
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int maxn = 9999999;
struct node
{int u, v, w;
};
bool cmp(node a, node b)
{return a.w < b.w;
}
int n;
node a[maxn];
int par[maxn];
int find(int x)
{if (par[x] == x)return x;return par[x] = find(par[x]);
}int main()
{cin >> n;for (int i = 0; i <= n; i++)par[i] = i;int cnt = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){int w; cin >> w;if (i != j){a[cnt].u = i;a[cnt].v = j;a[cnt].w = w;cnt++;}}}sort(a, a + cnt, cmp);int m; cin >> m;for (int i = 0; i < m; i++){int x, y;cin >> x >> y;int fx = find(x);int fy = find(y);par[fy] = fx;}int ans = 0;for (int i = 0; i < cnt; i++){int fa = find(a[i].u);int fb = find(a[i].v);if (fa != fb){par[fb] = fa;ans += a[i].w;}}cout << ans << endl;return 0;
}

poj 2421 ConstructingRoads 最小生成树 Prim、Kruskal相关推荐

  1. poj 2031 BuildingaSpaceStation 最小生成树 Prim、Kruskal

    题意: 三维空间里有一些球,给出球心坐标和半径,搭建通路,使得他们能够相互连通.如果两个球相交或者相切,则算已连通,无需再搭桥.求搭建通路的最小费用(费用就是边权,就是两个球面之间的距离). Inpu ...

  2. POJ 2421 Constructing Roads MST kruskal

    最近刚学的并查集所以用kruskal来试试最小生成树~ kruskal其实用几句话就能说完~  1.贪心所有边的权值,从小到大取值 2.取值时~将边权非0的两个顶点~进行并查操作~如果两个点的祖先不同 ...

  3. 数据结构实验之图论六:村村通公路(最小生成树Prim/Kruskal)

    Description 当前农村公路建设正如火如荼的展开,某乡镇政府决定实现村村通公路,工程师现有各个村落之间的原始道路统计数据表,表中列出了各村之间可以建设公路的若干条道路的成本,你的任务是根据给出 ...

  4. HDU 1233 还是畅通工程(最小生成树 Prim+Kruskal)

    原题地址 http://acm.hdu.edu.cn/showproblem.php?pid=1233 题意:(最小生成树裸题)有N个村庄,给出村庄两两之间的距离,要求铺设公路,使得任何两个村庄间都可 ...

  5. zoj 1586 QSNetwork 最小生成树 Prim Kruskal

    题意: 一个图,不止边有权值,点也有权值 Input: 输入的第一行包含一个整数t,它指示数据集的数量. 第二行中有T个数据集. 在单个数据集中,第一行包含一个整数n,表示qs的数目. 第2行包含n个 ...

  6. poj1861 最小生成树 prim amp; kruskal

    // poj1861 最小生成树 prim & kruskal // // 一个水题,为的仅仅是回味一下模板.日后好有个照顾不是#include <cstdio> #include ...

  7. * poj 1251 JungleRoad 最小生成树 Kruskal算法、Prim算法

    文章目录 Kruskal算法 模板:https://blog.csdn.net/Rain722/article/details/65642992 Prim算法 模板: poj 1251 JungleR ...

  8. 最小生成树算法详解(prim+kruskal)

    最小生成树概念: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里 ...

  9. ReviewForJob——最小生成树(prim + kruskal)源码实现和分析

    [0]README 1)本文旨在给出 ReviewForJob--最小生成树(prim + kruskal)源码实现和分析, 还会对其用到的 技术 做介绍: 2)最小生成树是对无向图而言的:一个无向图 ...

最新文章

  1. swing开发图形界面工具配置(可自由拖控件上去)
  2. DBShop前台RCE
  3. 编译linux tq2440,QT4.8.2在TQ2440开发板上的移植(一)--编译和安装
  4. Python中的星号:用途及使用方法(下篇)
  5. 聊聊代码质量 - 《学得会,抄得走的提升前端代码质量方法》前言
  6. Python图数据库neo4j学习实践
  7. Android模仿新浪微博(写微博界面)
  8. 华为手机自带浏览器的显示问题
  9. 计算机硬件主流参数,小白秒成DIY大神 自学电脑硬件参数速成攻略
  10. 建服务器数据中心,如何构建一个服务器数据中心
  11. 《机器学习:实用案例解析》第三章 (3)
  12. 小学五年级计算机教学论文,小学五年级数学教学论文
  13. 设计一个智能客服系统
  14. onCreate与onStart区别,onStart与onResume区别
  15. 教你解决线上频出MySQL死锁问题
  16. python画一颗小心心
  17. 原生JavaScript实现对象的完全深度拷贝
  18. 普元 AppServer 6.5 可以部署EOS导出的部署包吗?
  19. 图解UCWEB创业故事 痛并快乐着
  20. C艹开源可读项目整理

热门文章

  1. dhclient常用命令
  2. 配置管理-CMMI的五个等级
  3. webpack项目搭建
  4. 管理nuget程序包中搜索不到任何程序包
  5. 《数据结构C语言版》——线性表详解,你一定能够看得懂学得会的宝典
  6. android 源码中的单例,Android源码中的一种单例实现
  7. 一文搞懂Oracle 0 至 6 级锁(附案例详解)
  8. Oracle行迁移和行链接
  9. 【全干货】5分钟带你看懂 Docker!
  10. 辞旧迎新:2018年的分区你们建了吗?