CDOJ 1146 秋实大哥与连锁快餐店 Prim 最小生成树
2016-07-31 19:25
351 查看
嗯,题意就是说,平面坐标系上有n个点,它们可以形成一个完全图,距离就是两点的欧几里德距离
然后其中有一些点是旗舰店,然后现在想连一些边,使得所有的点都与至少一个旗舰店连通,然后问最小的边权和
显然就是最小生成树了
但是这是稠密图(其实我觉得即使稠密图,Kruskal的表现应该也很好,因为并查集部分的操作应该是近乎常数的吧),所以prim会更好
开始时用的Kruskal,直接MLE了,发现是内存限制比较小,然后也就放弃了堆优化 的prim,直接上普通的prim,然后就过了
然后其中有一些点是旗舰店,然后现在想连一些边,使得所有的点都与至少一个旗舰店连通,然后问最小的边权和
显然就是最小生成树了
但是这是稠密图(其实我觉得即使稠密图,Kruskal的表现应该也很好,因为并查集部分的操作应该是近乎常数的吧),所以prim会更好
开始时用的Kruskal,直接MLE了,发现是内存限制比较小,然后也就放弃了堆优化 的prim,直接上普通的prim,然后就过了
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <fstream> #include <list> #include <stack> #include <queue> #include <deque> #include <algorithm> #include <map> #include <set> #include <vector> using namespace std; #define ll long long #define INF 0x3f3f3f3f #define maxn 6700 #define maxm 23000000 pair<ll, ll> node[maxn]; int n; bool root[maxn]; ll dist[maxn]; double Prim() { double ans = 0; bool flag = true; ll tmp; for (int i = 0; i < n; ++i) { if (!root[i]) continue; if (flag) { for (int j = 0; j < n; ++j) { dist[j] = (node[i].first - node[j].first)*(node[i].first - node[j].first) + (node[i].second - node[j].second)*(node[i].second - node[j].second); } flag = false; } else { for (int j = 0; j < n; ++j) { tmp = (node[i].first - node[j].first)*(node[i].first - node[j].first) + (node[i].second - node[j].second)*(node[i].second - node[j].second); if (tmp < dist[j]) dist[j] = tmp; } } } for (int i = 0; i < n; ++i) { int k = -1; ll minv = 999999999999999; for (int j = 0; j < n; ++j) { if (!root[j] && dist[j] < minv) { k = j; minv = dist[j]; } } if (k == -1) break; root[k] = true; ans += sqrt(minv); for (int j = 0; j < n; ++j) { if (!root[j]) { tmp = (node[k].first - node[j].first)*(node[k].first - node[j].first) + (node[k].second - node[j].second)*(node[k].second - node[j].second); if (tmp < dist[j]) { dist[j] = tmp; } } } } return ans; } int main() { //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); //ios::sync_with_stdio(false); //cin.tie(0); cout.tie(0); //ifstream in; //in.open("input.txt", ios::in); scanf("%d", &n); int tmp; for (int i = 0; i < n; ++i) { scanf("%lld%lld%d", &node[i].first, &node[i].second, &tmp); if (tmp > 0) root[i] = true; } double ans; ans = Prim(); printf("%.2f\n", ans); //while (1); return 0; }
相关文章推荐
- CDOJ 1060 秋实大哥与快餐店 字典树
- UESTC_秋实大哥与连锁快餐店 2015 UESTC Training for Graph Theory<Problem A>
- cdoj 2015数据结构专题:C - 秋实大哥与快餐店
- 【POJ 2831】 Can We Build This One?(prim 最小生成树变形)
- 图论浅析--最小生成树之Prim
- POJ 1789 Truck History 最小生成树 prim
- NYOJ1239 引水工程(最小生成树,Prim)
- [kuangbin带你飞]专题六 最小生成树 (prim)(kruskal)(模板)
- 贪心法实现Prim最小生成树(java)
- 最小生成树之PRIM及KRUSCAL
- poj2485——Highways(最小生成树+prim)
- hdu1879 继续畅通工程 (最小生成树之prim 算法)
- 最小生成树-Prim
- HDUOJ_1875(最小生成树)(畅通工程再续)(克鲁斯卡尔和prim两种方法解)
- 最小生成树(prim和kruscal算法)
- Highways(prim——最小生成树)
- prim 最小生成树
- 最小生成树--prim+优先队列优化模板
- HDU 2489 Minimal Ratio Tree(dfs+最小生成树-Prim)
- 最小生成树 Kruskal&&Prim