hdu 4756 Install Air Conditioning
非正规做法,一个一个的暴,减一下枝,还得采用sort,qsort居然过不了……
- #include <cstdio>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- using namespace std;
- #define LL long long
- struct node{
- int u, v, no;
- LL dis;
- };
- int n, len, pos, p[1010], num[1010][2];
- double maxx;
- node v[500010], cnt[1010];
- LL dist(int i, int j){
- return (LL)(num[i][0] - num[j][0]) * (num[i][0] - num[j][0]) + (LL)(num[i][1] - num[j][1]) * (num[i][1] - num[j][1]);
- }
- bool cmp(const node &p1, const node &p2) {
- return p1.dis < p2.dis;
- }
- int find(int x) {
- return p[x] == x ? x : p[x] = find(p[x]);
- }
- void Kruskal(){
- sort(v, v + len, cmp);
- maxx = 0;
- pos = 0;
- int k = n - 1;
- for(int i = 0; i < n; ++i) p[i] = i;
- for(int i = 0; i < len; ++i){
- int x = find(v[i].u);
- int y = find(v[i].v);
- if(x!=y){
- maxx += sqrt((double)v[i].dis);
- p[x] = y;
- cnt[pos] = v[i];
- cnt[pos++].no = i;
- --k;
- if(!k) break;
- }
- }
- }
- void solve(){
- double t = maxx;
- for(int k = 0; k < pos; ++k){
- if(!cnt[k].u) continue;
- double e = t - sqrt((double)cnt[k].dis);
- for(int i = 0; i < n; ++i) p[i] = i;
- for(int i = 0; i < pos; ++i)
- if(i != k){
- int x = find(cnt[i].u);
- int y = find(cnt[i].v);
- p[x] = y;
- }
- for(int i = cnt[k].no + 1; i < len; ++i){
- int x1 = find(v[i].u);
- int y1 = find(v[i].v);
- if(x1 != y1){
- e += sqrt((double)v[i].dis);
- if(maxx < e) maxx = e;
- break;
- }
- }
- }
- }
- int main()
- {
- //freopen("in.txt", "r", stdin);
- int t, k;
- scanf("%d", &t);
- while(t--){
- scanf("%d %d", &n, &k);
- for(int i = 0; i < n; ++i)
- scanf("%d %d", &num[i][0], &num[i][1]);
- len = 0;
- for(int i = 0; i < n; ++i)
- for(int j = i+1; j < n; ++j){
- v[len].dis = dist(i, j);
- v[len].u = i;
- v[len++].v = j;
- }
- Kruskal();
- solve();
- printf("%.2lf\n", maxx * k);
- }
- return 0;
- }
- 第二次做:用dfs+并查集,速度果然提高了许多
- #include <cstdio>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- using namespace std;
- #define LL long long
- struct node{
- int u, v;
- LL dis;
- };
- int n, len, pos, p[1010], num[1010][2], head[1010], next[2010][3];
- double maxx, cnt;
- node v[500010];
- LL dist(int i, int j){
- return (LL)(num[i][0] - num[j][0]) * (num[i][0] - num[j][0]) + (LL)(num[i][1] - num[j][1]) * (num[i][1] - num[j][1]);
- }
- bool cmp(const node &p1, const node &p2) {
- return p1.dis < p2.dis;
- }
- int find(int x) {
- return p[x] == x ? x : p[x] = find(p[x]);
- }
- void add(int u, int v, int i){
- next[pos][1] = v;
- next[pos][2] = i;
- next[pos][0] = head[u];
- head[u] = pos++;
- }
- void Kruskal(){
- sort(v, v + len, cmp);
- maxx = 0;
- pos = 0;
- int k = n - 1;
- for(int i = 0; i < n; ++i) p[i] = i;
- for(int i = 0; i < len; ++i){
- int x = find(v[i].u);
- int y = find(v[i].v);
- if(x!=y){
- maxx += sqrt((double)v[i].dis);
- p[x] = y;
- add(v[i].u, v[i].v, i);
- add(v[i].v, v[i].u, i);
- --k;
- if(!k) break;
- }
- }
- }
- void dfs(int cur, int fa){
- for(int i = head[cur]; i != -1; i = next[i][0]){
- int u = next[i][1];
- int no = next[i][2];
- if(u != fa){
- dfs(u, cur);
- int x = find(cur);
- int y = find(u);
- if(u && cur){
- double t = maxx - sqrt(double(v[no].dis));
- for(int j = no + 1; j < len; ++j){
- int x1 = find(v[j].u);
- int y1 = find(v[j].v);
- if(x1 != y1 && (x1 == y || y1 == y)){
- cnt = max(cnt, t + sqrt(double(v[j].dis)));
- break;
- }
- }
- }
- p[x] = y;
- }
- }
- }
- int main()
- {
- // freopen("in.txt", "r", stdin);
- int t, k;
- scanf("%d", &t);
- while(t--){
- scanf("%d %d", &n, &k);
- for(int i = 0; i < n; ++i)
- scanf("%d %d", &num[i][0], &num[i][1]), head[i] = -1;
- len = 0;
- for(int i = 0; i < n; ++i)
- for(int j = i+1; j < n; ++j){
- v[len].dis = dist(i, j);
- v[len].u = i;
- v[len++].v = j;
- }
- Kruskal();
- for(int i = 0; i < n; ++i) p[i] = i;
- cnt = maxx;
- dfs(0, -1);
- printf("%.2lf\n", cnt * k);
- }
- return 0;
- }
- 第三次做:采用普里姆算法,果然快了很多,适用于稠密图,也就是边比较多的图,N^2的算法,网上大多数采用普里姆算法+树形dp,我是采用普里姆算法然后dfs优化做的,c++也照样过
- #include <cstdio>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- using namespace std;
- #define LL long long
- LL inf = 10000000000000000LL;
- int n, dfs_cnt, p[1010], num[1010][2], head[1010], next[2010][2];
- double maxx, q;
- bool flag;
- LL v[1005][1005], cnt[1010], arr[1005][1005];
- LL dist(int i, int j)
- {
- return (LL)(num[i][0] - num[j][0]) * (num[i][0] - num[j][0]) + (LL)(num[i][1] - num[j][1]) * (num[i][1] - num[j][1]);
- }
- void add(int u, int v){
- next[dfs_cnt][1] = v;
- next[dfs_cnt][0] = head[u];
- head[u] = dfs_cnt++;
- }
- void prim()
- {
- maxx = 0, dfs_cnt = 0;
- for(int i = 1; i < n; ++i){
- cnt[i] = v[0][i];
- p[i] = 0;
- }
- cnt[0] = 0, p[0] = 0;
- for(int i = 1; i < n; ++i){
- int k = 0;
- LL c = inf;
- for(int j = 1; j < n; ++j)
- if(cnt[j] != 0 && cnt[j] < c){
- c = cnt[j];
- k = j;
- }
- add(p[k], k);
- add(k, p[k]);
- maxx += sqrt(double(c));
- cnt[k] = 0;
- for(int j = 1; j < n; ++j)
- if(cnt[j] != 0 && v[k][j] < cnt[j]){
- cnt[j] = v[k][j];
- p[j] = k;
- }
- }
- }
- double tarjan(int cur, int fa, int pos, LL f){
- double c = inf;
- for(int i = head[cur]; i != -1; i = next[i][0]){
- int u = next[i][1];
- if(u != fa){
- c = min(c, tarjan(u, cur, pos, f));
- if(arr[u][pos] != f) c = min(c, sqrt(double(arr[u][pos])) - sqrt(double(f)));
- else if(flag) c = min(c, 0.0);
- else flag = 1;
- //printf("%.2lf ", c);
- }
- }
- return c;
- }
- void dfs(int cur, int fa){
- for(int i = head[cur]; i != -1; i = next[i][0]){
- int u = next[i][1];
- if(u != fa){
- dfs(u, cur);
- if(u && cur){
- double c = inf;
- for(int j = 0; j < n; ++j)
- if(j != cur)
- c = min(c, sqrt(double(v[u][j])) - sqrt(double(v[u][cur])));
- flag = 0;
- if(arr[u][cur] == v[u][cur]) flag = 1;
- else c = min(c, sqrt(double(arr[u][cur])));
- c = min(c, tarjan(u, cur, cur, v[u][cur]));
- maxx = max(maxx, q + c);
- }
- v[u][cur] = v[cur][u] = inf;
- for(int j = 0; j < n; ++j)
- if(v[cur][j] == inf || v[u][j] == inf) v[cur][j] = inf;
- else v[cur][j] = min(v[cur][j], v[u][j]);
- }
- }
- }
- int main()
- {
- // freopen("in.txt", "r", stdin);
- int t, k;
- scanf("%d", &t);
- while(t--){
- scanf("%d %d", &n, &k);
- for(int i = 0; i < n; ++i)
- scanf("%d %d", &num[i][0], &num[i][1]), head[i] = -1;
- for(int i = 0; i < n; ++i){
- arr[i][i] = v[i][i] = inf;
- for(int j = i + 1; j < n; ++j)
- if(i != j) arr[i][j] = arr[j][i] = v[i][j] = v[j][i] = dist(i, j);
- }
- prim();
- q = maxx;
- dfs(0, -1);
- printf("%.2lf\n", maxx * k);
- }
- return 0;
- }
hdu 4756 Install Air Conditioning的更多相关文章
- HDU 4756 Install Air Conditioning(次小生成树)
题目大意:给你n个点然后让你求出去掉一条边之后所形成的最小生成树. 比較基础的次小生成树吧. ..先prime一遍求出最小生成树.在dfs求出次小生成树. Install Air Conditioni ...
- HDU 4756 Install Air Conditioning (MST+树形DP)
题意:n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个位置连通的最小花费的最大值. 析:因为要连通,还要权值最小,所以就是MST了,然后就是改变一条边,然后去找出改变 ...
- Install Air Conditioning HDU - 4756(最小生成树+树形dp)
Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...
- hdu4756 Install Air Conditioning(MST + 树形DP)
题目请戳这里 题目大意:给n个点,现在要使这n个点连通,并且要求代价最小.现在有2个点之间不能直接连通(除了第一个点),求最小代价. 题目分析:跟这题一样样的,唉,又是原题..先求mst,然后枚举边, ...
- MST(prim)+树形dp-hdu-4756-Install Air Conditioning
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4756 题目意思: n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个 ...
- 每日英语:Can Going In and Out of Air Conditioning Cause Colds?
For most people, summer involves numerous daily shifts between scorching outdoor heat and frosty air ...
- hdu 4756 MST+树形dp ****
题意:给你n(n = 1000)个二维点,第一个点是power plant,还有n - 1个点是dormitories.然后现在知道有一条寝室到寝室的边是不能连的,但是我们不知道是哪条边,问这种情况下 ...
- 【转载】ACM总结——dp专辑
感谢博主—— http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 动态规划一 ...
- 【DP专辑】ACM动态规划总结
转载请注明出处,谢谢. http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 ...
随机推荐
- mysql存储过程、函数和触发器的创建 [转]
http://blog.itpub.net/559237/viewspace-438942/ 今天花了半天时间来研究mysql的存储过程函数和触发器的创建,觉得和oracle的大同小异,只是语法上更艰 ...
- [RxJS] Refactoring CombineLatest to WithLatestFrom
This lesson shows why it’s preferable to using withLatestFrom instead of combineLatest in certain sc ...
- VS2010调试小技巧
在VS下做开发的时候我们进行调试的时候路径是这个样子的:http://localhost:端口号/项目名称/index.aspx 但是发布到服务器上面的时候却是这个样子的:http://www.xxx ...
- 怎么样学好C++
声明:这篇文章非本人所写,转自:http://coolshell.cn/articles/4119.html 昨天写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写 ...
- 重学《C#高级编程》(序)
小生码农一枚,以前只是看别人写博客,从来没有想过要自己写博文,突然之间“脑抽”想自己也写点什么,遂在博客园开通这个博客. 简单介绍下自己吧,本人90后,父母对我没有大的想法,只是希望我平安成长,多学习 ...
- Lesson 2: Dive Into Typography (排版)
Lesson 2: Dive Into Typography (排版) 排版是字的艺术,是关于字的一切:字体.字号.行高.行长.字重(斜体/加粗/正常).字距(kerning).行距(leading) ...
- 活动指示器UIActivityIndicatorView
活动指示器UIActivityIndicatorView可以告知用户有一个操作正在进行中 1.创建 UIActivityIndicatorView *activityIndicatorView ...
- FileStream 操作文件复制
static void Main(string[] args) { string source = @"D:\c\集合.avi"; string target = @"C ...
- StringBuilder 大量字符串时使用,速度比较快
public static void Main(string[] args) { Stopwatch sw = new Stopwatch(); //程序计时器 StringBuilder str = ...
- 用ThreadLocal管理事务
1.适用场景 一个service,操作两个dao,要求两个dao为同一个事务,要么全成功,要么全失败.