UVA1151
//感觉刘汝佳老师的思维真的太厉害了orz /*摘录书上的一段话: 只需一个小小的优化即可降低时间复杂度:先求一次原图(不购买任何套餐)的最小生 成树,得到n-1条边,然后每次枚举完套餐后只考虑套餐中的边和这n-1条边,则枚举套餐之 后再求最小生成树时,图上的边已经寥寥无几。 为什么可以这样呢?首先回顾一下,在Kruskal算法中,哪些边不会进入最小生成树。答 案是:两端已经属于同一个连通分量的边。买了套餐以后,相当于一些边的权变为0,而对 于不在套餐中的每条边e,排序在e之前的边一个都没少,反而可能多了一些权值为0的边, 所以在原图Kruskal时被“扔掉”的边,在后面的Kruskal中也一样会被扔掉。*/ // UVa1151 Buy or Build // Rujia Liu #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<algorithm> using namespace std; + ; ; int n; int x[maxn], y[maxn], cost[maxq]; vector<int> subn[maxq]; int pa[maxn]; int findset(int x) { return pa[x] != x ? pa[x] = findset(pa[x]) : x; } struct Edge { int u, v, d; Edge(int u, int v, int d):u(u),v(v),d(d) {} bool operator < (const Edge& rhs) const { return d < rhs.d; } }; // initialize pa and sort e before calling this method // cnt is the current number of components int MST(int cnt, const vector<Edge>& e, vector<Edge>& used) { //找出原图跑一边kruskal之后用过的边 ) ; int m = e.size(); ; used.clear(); ; i < m; i++) { int u = findset(e[i].u), v = findset(e[i].v); int d = e[i].d; if(u != v) { pa[u] = v; ans += d; used.push_back(e[i]); ) break; } } return ans; } int main() { int T, q; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &q); ; i < q; i++) { int cnt; scanf("%d%d", &cnt, &cost[i]); subn[i].clear(); while(cnt--) { int u; scanf("%d", &u); subn[i].push_back(u-); } } ; i < n; i++) scanf("%d%d", &x[i], &y[i]); vector<Edge> e, need; ; i < n; i++) ; j < n; j++) { int c = (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]); e.push_back(Edge(i, j, c)); } ; i < n; i++) pa[i] = i; sort(e.begin(), e.end()); int ans = MST(n, e, need); ; mask < (<<q); mask++) { //枚举套餐,二进制法 // union cities in the same sub-network ; i < n; i++) pa[i] = i; ; ; i < q; i++) <<i)) { c += cost[i]; ; j < subn[i].size(); j++) { ]); if(u != v) { pa[u] = v; cnt--; } } } vector<Edge> dummy; ans = min(ans, c + MST(cnt, need, dummy)); } printf("%d\n", ans); if(T) printf("\n"); } ; }
UVA1151的更多相关文章
- UVa1151 Buy or Build
填坑(p.358) 以前天真的以为用prim把n-1条边求出来就可以 现在看来是我想多了 #include<cstdio> #include<cstring> #include ...
- 【最小生成树+子集枚举】Uva1151 Buy or Build
Description 平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方. 另外还有q(0<=q< ...
- Buy or Build(UVa1151)
如果枚举每个套餐,并每次都求最小生成树,总时间复杂度会很高,因而需要先求一次原图的最小生成树,则枚举套餐之后需要考虑的边大大减少了. 具体见代码: #include<cstdio> #in ...
- 洛谷 题解 UVA1151 【买还是建 Buy or Build】
[题意] 平面上有\(n(n<=1000)\)个点,你的任务是让所有n个点联通.为此,你可以新建一些边,费用等于两个端点的欧几里得距离平方.另外还有\(q(q<=8)\)个套餐可以购买,如 ...
- UVA 1151 买还是建(最小生成树)
买还是建 紫书P358 [题目链接]买还是建 [题目类型]最小生成树 &题解: 这题真的心累,看了3天,最后照着码还是wa,先放lrj代码,以后再看吧 &代码: // UVa1151 ...
- UVa 1151 买还是建
https://vjudge.net/problem/UVA-1151 题意: 平面上有n个点,你的任务是让所有n个点连通.为此,你可以新建一些边,费用等于两个端点的距离平方和.另外还有q个套餐可以购 ...
- uva 1511 最小生成树
https://vjudge.net/problem/UVA-1151 题意,给出N个点以及二维坐标,可以在任意两点间建立通路,代价是两点欧几里得距离的平方,同时有q个套餐,套餐x有qx个点,代价是q ...
随机推荐
- MySQL基础之第18章 性能优化
18.1.优化简介 SHOW STATUS LIKE ‘value’;connections 连接数uptime 启动 ...
- 使用Junit实现批量运行
我们知道使用testng可以很方便的实现批量运行,但有的同学更习惯用junit,那么junit是否也有批量运行的功能呢?答案是 YES,而且有2种方法: 第一种, 选择要测试的包(注意是包而不是文件) ...
- LR之配置端口映射(port mapping)
1.那些协议需要配置 tools-recording_options-network-port mapping 2.定义端口映射 3.自动检测原理 4.特殊情况
- hadoop是什么?
在如今这个信息高速发展的今天,hadoop也越来越火了,那么到底是什么原因让hadoop如此的火,接下来新霸哥将详细的为了介绍,并让你快速的任何hadoop是什么? hadoop思想起源:Google ...
- 转——使用Axure制作App原型应该怎样设置尺寸?
想用Axure设计一个 APP原型 放到真实的移动设备中演示,但不知道应该使用什么尺寸?若要解释清楚像素和分辨率需要的篇幅比较长,请大家参考百度百科.这里金乌直接给大家提供一个常用的移动设备尺寸列表, ...
- [转]简析 IOS 程序图标的设计
表现形态**** 在有限的空间里表达出相对应的信息,在IOS 程序图标设计中,直观是第一个解决的问题,不应该出现大多繁琐的修饰,当然还要有很好的视觉表现力,使用户可以更容易理解此应用的实际作用,更轻松 ...
- leetcode–jump game II
1.题目描述 Given an array of non-negative integers, you are initially positioned at the first index of t ...
- LeetCode(8) - String to Integer (atoi)
虽然是easy,却是比较繁琐的一道题,需要考虑各种边界条件.在WA了好几遍之后,才把各种边界条件给补全.需要考虑到的因素如下: 输入不合法字符,非"0-9",对于首位,合法字符还包 ...
- springMVC的详细步骤配置
使用springMVC也可以代替struts2,当然只是代替业务分发的功能,struts2的一些其他功能它是没有的,不然要struts2有什么用. 下面我用springMVC代替struts2去整合h ...
- 指定的值不是类型“Edm.Int32”的实例
指定的值不是类型“Edm.Int32”的实例参数名: value 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常 ...