UVa1151 Buy or Build
2016-01-08 15:10
411 查看
填坑(p.358)
以前天真的以为用prim把n-1条边求出来就可以
现在看来是我想多了
View Code
以前天真的以为用prim把n-1条边求出来就可以
现在看来是我想多了
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> const int N = 1000 + 10; struct Node { int x, y; Node(int x = 0, int y = 0) : x(x), y(y) {} }p ; int sqr(int x) { return x * x; } int dist(const Node& a, const Node& b) { return sqr(a.x - b.x) + sqr(a.y - b.y); } struct Edge { int u, v, w; Edge() {} Edge(int u, int v, int w) : u(u), v(v), w(w) {} bool operator < (const Edge& rhs) const { return w < rhs.w; } }; #include<vector> std::vector<Edge> edges, pree; int n, ans; int d , pre , dis ; bool inMST ; void prim() { memset(d, 0x3f, sizeof d); memset(inMST, 0, sizeof inMST); ans = d[0] = 0; for(int i = 0; i < n; i++) { int u = -1; for(int v = 0; v < n; v++) if(!inMST[v]) { if(u == -1 || d[v] < d[u]) u = v; } inMST[u] = 1; ans += d[u]; if(i) edges.push_back(Edge(u, pre[u], dis[u][pre[u]])); for(int v = 0; v < n; v++) if(!inMST[v]) { if(d[v] > d[u] + dis[u][v]) { d[v] = d[u] + dis[u][v]; pre[v] = u; } } } } int fa ; int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } bool merge(int x, int y) { x = find(x), y = find(y); if(x == y) return 0; return fa[x] = y, 1; } void UFS_init() { for(int i = 0; i < n; i++) fa[i] = i; } void pre_kruskal() { for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { pree.push_back(Edge(i, j, dis[i][j])); } } sort(pree.begin(), pree.end()); UFS_init(); int MST = n; ans = 0; for(unsigned i = 0; i < pree.size(); i++) { const Edge& e = pree[i]; if(merge(e.u, e.v)) { edges.push_back(e); ans += e.w; if(--MST == 1) break; } } } int q; #include<vector> std::vector<int> frees[10]; int cost[10]; #include<cassert> void Kruskal(int mask) { UFS_init(); int MST = n, res = 0; for(int j = 0; j < q; j++) if(mask >> j & 1) { res += cost[j]; for(unsigned i = 1; i < frees[j].size(); i++) { MST -= merge(frees[j][i-1], frees[j][i]); } } for(unsigned i = 0; i < edges.size(); i++) { if(MST == 1) break; if(merge(edges[i].u, edges[i].v)) res += edges[i].w, MST--; } assert(MST == 1); ans = std::min(ans, res); } int main() { #ifdef DEBUG freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int T; scanf("%d", &T); while(T--) { pree.clear(); edges.clear(); scanf("%d%d", &n, &q); for(int i = 0; i < q; i++) { int m; scanf("%d%d", &m, cost + i); frees[i].resize(m); for(int j = 0; j < m; j++) { scanf("%d", &frees[i][j]); --frees[i][j]; } } for(int i = 0; i < n; i++) { scanf("%d%d", &p[i].x, &p[i].y); for(int j = 0; j < i; j++) { dis[i][j] = dis[j][i] = dist(p[i], p[j]); } } pre_kruskal(); std::sort(edges.begin(), edges.end()); for(int mask = 0; mask < (1 << q); mask++) { Kruskal(mask); } printf("%d\n", ans); if(T) puts(""); } return 0; }
View Code
相关文章推荐
- IOS开发~UISCrollView与UITableView嵌套使用终极解决方案
- 在UIView页面执行pushViewController操作
- iOS Newbie - Xcode 7 & iOS 9 UITextField & UITextView
- UEditor图片路径-从后台传递参数
- 自定义UISlider的样式和滑块
- 01-08 UICollectionView 例子
- UISlider自定义高度
- UIAlertController中添加DatePicker
- It is indirectly referenced from required class file ... could not find class......
- easyUI tree以及tab的创建以及应用
- bluedroid 代码框架
- UITableView使用小结(滚动到顶部、获取cell、cell选中状态、刷新cell或者section)
- UVa 12100 - Printer Queue【队列和优先队列】
- Android 更新UI的两种方法——handler和runOnUiThread()
- Android Build类
- 【LeetCode】Repeated DNA Sequences 解题报告
- Request与Response常用方法总结
- Android Contacts (一)ContentResolver query 参数详解
- UIPickerView组件的使用之——省市联动
- Map对value进行排序