Tyvj 1391 走廊泼水节 - 生成树 - 完全图
2017-10-20 20:15
417 查看
题目大意:
给定一个完全图的唯一最小生成树,求这个完全图最小的边权和
完全图:结点两两之间都有边的图
首先我第一回做的时候写了个map骗分的做法。。。我以为N2logN可以过40%数据的,然而被多组数据卡时间了Orz
但!是!map仍然是一个高速骗分利器
所以我先总结下map的用法
map是一类容器,他可以做到哈希表能做的事,其内部由红黑树实现,因此效率十分高。
然后map是拿来做映射的,比如说我想要判断一个坐标(x,y)是否存在过,那我可以
第一个参数是索引,第二个参数是实际值,我每次
就可以判重
而且他那个id[]里什么都能放,你甚至可以放一个动态
dc96
数组或者字符串进去。
还有一种我特别喜欢的用法,就是类似哈希的挂链
我们可以
想要遍历vector数组,需要建立一个迭代器
遍历则是
.end()返回的是最后一个元素的后一个位置的指针
注意 这里it是指针,需要*it来求值
可以把输入给的边来一次kruskal的过程,按权值排序,忽视之前的所有边,用并查集连接两个集合。
设想我们有两个点集合,x和y,两个集合之间因为一条边权为w的边要合并了
我们把x集合的每个点和y集合的所有点连边,就是一个完全图了,现在需要考虑那些边的边权。
由于我们是按照边权排序的,w此时一定为图中最大边,而题目要求为了最小生成树,也就是说我们新加入的边不能成为最小生成树的一部分,他不能比图中任何边小,这条边的权值又需要为整数,那自然就是w+1,我们此时就增加了(x∗y−1)∗(w+1)边权
给定一个完全图的唯一最小生成树,求这个完全图最小的边权和
完全图:结点两两之间都有边的图
首先我第一回做的时候写了个map骗分的做法。。。我以为N2logN可以过40%数据的,然而被多组数据卡时间了Orz
但!是!map仍然是一个高速骗分利器
所以我先总结下map的用法
map是一类容器,他可以做到哈希表能做的事,其内部由红黑树实现,因此效率十分高。
然后map是拿来做映射的,比如说我想要判断一个坐标(x,y)是否存在过,那我可以
map<pair<int, int>, bool> id
第一个参数是索引,第二个参数是实际值,我每次
if(id[make_pair(a,b)])
就可以判重
而且他那个id[]里什么都能放,你甚至可以放一个动态
dc96
数组或者字符串进去。
还有一种我特别喜欢的用法,就是类似哈希的挂链
我们可以
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,我们此时就增加了(x∗y−1)∗(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 走廊泼水节【最小生成树】By cellur925
- tyvj1391 走廊泼水节
- TYVJ 1391 走廊泼水节
- tyvj 1391 走廊泼水节
- Tyvj P1391 走廊泼水节
- 大家来帮忙看看啊,为什么老是显示LINK : 没有找到 C:/Documents and Settings/Administrator/桌面/端口扫描/Debug/端口扫描.exe 或上一个增量链接没有生成它;正在执行完全链接
- tyvj 1214 硬币问题 完全背包 恰好 最大/最少
- IAR编译ZStack-CC2530,生成HEX文件完全配置
- 结合JsBarcode文档整理出来的一个demo,完全够用,生成和打印条形码
- Drawable转换生成bitMapDrawable的完全实现方法
- 想完全使用代码动态生成GridView真难
- TYVJ-P1214 硬币问题-完全背包
- ink 没有找到 或上一个增量链接没有生成它;正在执行完全链接
- 《ASP.NET2.0揭秘》读书笔记——构建完全生成控件
- axis2 在myeclipse中生成webservice aar文件时 为嘛有时候点击next完全没反应啊,在线等。。。。
- 最小生成树 tyvj 连接格点grid
- 51nod 1601 完全图的最小生成树计数 Trie+kruskal
- LINK : 没有找到 *.exe 或上一个增量链接没有生成它;正在执行完全链接
- 附加数据库报错:由于数据库没有完全关闭,无法重新生成日志
- error PRJ0050: 未能注册输出。或上一个增量链接没有生成它;正在执行完全链接问题的解决