Tyvj 1391 走廊泼水节
来源:互联网 发布:eplan软件使用心得 编辑:程序博客网 时间:2024/05/16 23:47
题目大意:
给定一个完全图的唯一最小生成树,求这个完全图最小的边权和
完全图:结点两两之间都有边的图
首先我第一回做的时候写了个map骗分的做法。。。我以为
但!是!map仍然是一个高速骗分利器
所以我先总结下map的用法
map是一类容器,他可以做到哈希表能做的事,其内部由红黑树实现,因此效率十分高。
然后map是拿来做映射的,比如说我想要判断一个坐标(x,y)是否存在过,那我可以map<pair<int, int>, bool> id
第一个参数是索引,第二个参数是实际值,我每次if(id[make_pair(a,b)])
就可以判重
而且他那个id[]里什么都能放,你甚至可以放一个动态数组或者字符串进去。
还有一种我特别喜欢的用法,就是类似哈希的挂链
我们可以map<int, vector<int> > id
注意,这里最右边一定要写成> >(带空格),不然编译器会识别为“>>”
想要遍历vector数组,需要建立一个迭代器 vector<int> :: iterator it
遍历则是for(it=id[x].begin(); it<id[x].end(); it++)
.end()返回的是最后一个元素的后一个位置的指针
注意 这里it是指针,需要*it来求值
正解
我们需要高速确定点对之间是否有边以及点对之间新建边的最小权值
可以把输入给的边来一次kruskal的过程,按权值排序,忽视之前的所有边,用并查集连接两个集合。
设想我们有两个点集合,x和y,两个集合之间因为一条边权为w的边要合并了
我们把x集合的每个点和y集合的所有点连边,就是一个完全图了,现在需要考虑那些边的边权。
由于我们是按照边权排序的,w此时一定为图中最大边,而题目要求为了最小生成树,也就是说我们新加入的边不能成为最小生成树的一部分,他不能比图中任何边小,这条边的权值又需要为整数,那自然就是w+1,我们此时就增加了
#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <map>const int MAXN = 20010;using namespace std;int fa[MAXN],node[MAXN],rk[MAXN];#define debug(x) cerr << #x << "=" << x << endl;int tot,last[MAXN],depth[MAXN];long long total;long long ans, answ;int vis[MAXN],n,t;struct Edge{ int u,v,w,to; Edge(){} Edge(int u, int v, int w, int to) : u(u), v(v), w(w), to(to) {}}e[MAXN*2];inline void add(int u, int v, int w) { e[++tot] = Edge(u,v,w,last[u]); last[u] = tot;}void init() { memset(last,0,sizeof(last)); tot = 0; ans = 0; answ = 0; total = 0; memset(e,0,sizeof(e)); memset(depth,0,sizeof(depth)); memset(vis,0,sizeof(vis)); memset(fa,0,sizeof(fa)); memset(rk,0,sizeof(rk)); memset(node,0,sizeof(node));}bool cmp(Edge a, Edge b) { return a.w < b.w;}int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]);}bool jud(int a, int b) { return find(a) == find(b);}void merge(int a,int b) { node[find(b)] += node[find(a)]; fa[find(a)] = find(b);}int main() { scanf("%d",&t); while(t--) { init(); scanf("%d", &n); for(int i=1; i<n; i++) { int u,v,w; scanf("%d %d %d",&u,&v,&w); total += w; add(u,v,w); add(v,u,w); } for(int i=1; i<=n; i++) { fa[i] = i; rk[i] = 1; node[i] = 1; } sort(e+1,e+tot+1,cmp); for(int i=1; i<=tot; i++) { int u = e[i].u; int v = e[i].v; if(!jud(u,v)) { ans += (long long)(e[i].w+1)*((long long)(node[find(u)])*(node[find(v)]) - 1); merge(u,v); } } printf("%lld\n",ans); } return 0;}
- tyvj 1391 走廊泼水节
- TYVJ 1391 走廊泼水节
- Tyvj 1391 走廊泼水节
- Tyvj P1391 走廊泼水节
- Tyvj P1391 走廊泼水节
- tyvj1391 走廊泼水节
- 图片走廊
- 我们的泼水节
- TYVJ
- 泼水节ING......丨暹罗猫佛牌
- 泼水节有什么来历吗?
- 开放瓦罕走廊
- 监控 走廊模式
- 亚当·扎加耶夫斯基《走廊》
- sdut 无尽走廊
- A 走廊两边搬桌子
- 无尽走廊(C语言)
- HDU-1050 走廊搬桌子
- 数据库activity的调用
- 三级缓存
- TLS/SSL握手过程
- 网络编码相关问题
- 南阳理工_69数的长度
- Tyvj 1391 走廊泼水节
- 我的第一个Java
- 使用Jmeter发送post请求的两种方式
- OpenCV的霍夫变换(Hough Transform)直线检测
- java打印水仙花数
- django表单提交错误
- bash处理一条命令的步骤
- CAS-3.5.2(一) 搭建开发环境
- Linux 安装redis及redis扩展