POJ 2421 Constructing Roads(并查集+最小生成树)
2016-03-18 10:43
471 查看
题目链接:
POJ 2421 Constructing Roads
题意:
给出n个点两两之间的权值,然后有m对a,b,表示a,b已经连通了。
问将这n个点都连通最少权值和是多少。
分析:
将m对已连通的点对用并查集合并,然后用Kruskal算法即可。
CODE:
POJ 2421 Constructing Roads
题意:
给出n个点两两之间的权值,然后有m对a,b,表示a,b已经连通了。
问将这n个点都连通最少权值和是多少。
分析:
将m对已连通的点对用并查集合并,然后用Kruskal算法即可。
CODE:
//804K 47MS #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int maxn=110; int n,ans,tot,m,u,v,w; int pre[maxn]; struct Edge{ int u,v,w; }edge[maxn*maxn]; void init() { ans=tot=0; for(int i=0;i<maxn;i++) pre[i]=i; } bool cmp(struct Edge a,struct Edge b) { return a.w<b.w; } int find(int x) { return pre[x]==x?x:pre[x]=find(pre[x]); } void mix(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) pre[fx]=fy; } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif while(~scanf("%d",&n)) { init(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&edge[tot].w); edge[tot].u=i; edge[tot].v=j; tot++; } } sort(edge,edge+tot,cmp); scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); mix(u,v); } for(int i=0;i<tot;i++) { u=edge[i].u; v=edge[i].v; w=edge[i].w; int fu=find(u); int fv=find(v); //printf("u=%d fu=%d v=%d fv=%d\n",u,fu,v,fv); if(fu!=fv) { pre[fu]=fv; ans+=w; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- 详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)
- 最小生成树算法之Prim算法
- 使用C语言实现最小生成树求解的简单方法
- 最小生成树算法——Prim和Kruskal算法的实现
- Data Structure - Week 15
- poj 2485 Highways
- HDU1301 最小生成树kruskal裸题
- Kruskal 最小生成树
- 最小生成树
- 图的最小生成树学习笔记
- BestWiring——Kruskal算法&并查集
- 克如斯卡尔算法--最小生成树
- 普里姆算法--最小生成树
- poj2395 解题报告
- 杭电1233
- HDU-1233 还是畅通工程(最小生成树&并查集)
- 最小生成树之克鲁斯卡尔算法
- 算法——图之加权图
- 浅析最小生成树和单源最短路径的区别(含Prim、Kruskal、Dijkstra、Bellman-Ford)
- IOS 9 支持的转场类型(segue)