组织集体活动
2016-03-22 00:37
232 查看
题目链接:http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1081
直接套用克鲁斯卡尔算法模板
直接套用克鲁斯卡尔算法模板
#include<iostream> #include<string.h> #include<algorithm> using namespace std; #define N 1000 struct graph { int u,v,cost; //顶点u和顶点V的边权是cost void set(int a,int b,int w){u=a,v=b,cost=w;} }; graph d[N*(N+1)/2]; //对于有n个顶点的图,边的数量是e<=n(n+1)/2 int father ; int Find(int x) { if (father[x]==-1) return x; return father[x] = Find(father[x]); } bool Union(int x, int y) { //判断两元素是否属于同一个集合,只要看看他们所在的集合的祖先是否相同 x = Find(x); y = Find(y); //祖先相同,是一个集合 if (x==y) return false; //祖先不同,合并两个集合 if (x>y) father[x] = y; if (x<y) father[y] = x; return true; } //按照边权的递增顺序排序 int cmp(graph x,graph y) { if (x.cost<y.cost) return true; return false; } int main() { int n, m; while (scanf("%d%d", &n, &m)!=EOF && n) { int i; int v,w,edge; //假设有m条边,每条边描述是(v,w,edge)表示顶点v到顶点w的边权是edge,则构造边集合d如下: for (i=0; i<m; i++) { scanf("%d%d%d", &v, &w, &edge); d[i].set(v,w,edge); } sort(d, d+m, cmp); memset(father, -1, sizeof(father)); int sum=0; //最小生成树中边权的和 int count=0; //查找每一条边 for(i=0; i<n*(n+1)/2; i++) { //找到一条满足的边 if (Union(d[i].u, d[i].v)) { // printf("%d %d\n", d[i].u, d[i].v); sum += d[i].cost; ++count; } if (count==n-1) break; else { cout<<"Impossible"<<endl; return 0; } } printf("%d\n",sum); } return 0; }
相关文章推荐
- 包分类算法性能(截图)
- 苹果营销总监称已不需要打广告
- Android之使用getIdentifier()获取资源Id
- 逻辑架构和物理架构
- Android自定义View
- 世界大部分的变化变革是一直有人在问为什么不能做得更好。
- Java HashMap的hash和indexFor函数
- prictice
- service和intentService的区别
- VIM编辑器的命令
- true_kb
- HashSet的add(E e)方法剖析
- 美术馆(完)
- Android BLE学习(三):编写自己的 BLE蓝牙读写工具(功能仿照nrf master control panel)
- android学习笔记——viewPager(适配器、常用函数、监听器、切换动画)
- android学习笔记——webView
- 排序算法---选择排序
- HashTable 和 HashMap的区别
- Web页面的请求历程
- android学习笔记——Fragment