HDU 4756 Install Air Conditioning(次小生成樹)
題目大意:給你n個點然後讓你求出去掉一條邊之後所形成的最小生成樹。
比較基礎的次小生成樹吧。。。先prime一遍求出最小生成樹,在dfs求出次小生成樹。
Install Air Conditioning
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 1038 Accepted Submission(s): 240
Problem Description
NJUST carries on the tradition of HaJunGong. NJUST, who keeps up the ”people-oriented, harmonious development” of the educational philosophy and develops the ”unity, dedication, truth-seeking, innovation” school motto, has now become an engineering-based, multidisciplinary university.
As we all know, Nanjing is one of the four hottest cities in China. Students in NJUST find it hard to fall asleep during hot summer every year. They will never, however, suffer from that hot this year, which makes them really excited. NJUST’s 60th birthday is approaching, in the meantime, 50 million is spent to install air conditioning among students dormitories. Due to NJUST’s long history, the old circuits are not capable to carry heavy load, so it is necessary to set new high-load wires. To reduce cost, every wire between two dormitory is considered a segment. Now, known about all the location of dormitories and a power plant, and the cost of high-load wire per meter, Tom200 wants to know in advance, under the premise of all dormitories being able to supply electricity, the minimum cost be spent on high-load wires. And this is the minimum strategy. But Tom200 is informed that there are so many wires between two specific dormitories that we cannot set a new high-load wire between these two, otherwise it may have potential risks. The problem is that Tom200 doesn’t know exactly which two dormitories until the setting process is started. So according to the minimum strategy described above, how much cost at most you'll spend?
Input
The first line of the input contains a single integer T(T ≤ 100), the number of test cases.
For each case, the first line contains two integers n(3 ≤ n ≤ 1000), k(1 ≤ k ≤ 100). n represents n-1 dormitories and one power plant, k represents the cost of high-load wire per meter. n lines followed contains two integers x, y(0 ≤ x, y ≤ 10000000), representing the location of dormitory or power plant. Assume no two locations are the same, and no three locations are on a straight line. The first one is always the location of the power plant.
For each case, the first line contains two integers n(3 ≤ n ≤ 1000), k(1 ≤ k ≤ 100). n represents n-1 dormitories and one power plant, k represents the cost of high-load wire per meter. n lines followed contains two integers x, y(0 ≤ x, y ≤ 10000000), representing the location of dormitory or power plant. Assume no two locations are the same, and no three locations are on a straight line. The first one is always the location of the power plant.
Output
For each case, output the cost, correct to two decimal places.
Sample Input
2
4 2
0 0
1 1
2 0
3 1
4 3
0 0
1 1
1 0
0 1
Sample Output
9.66
9.00
#include <set>
#include <map>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define LL __int64
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1010;
const int N = 1010;
const int M = 300010;
struct node
{
int x, y;
} p[maxn];
struct node1
{
int to, next;
} f[M];
int pre[N], head[N], flag[N];
int vis[N][N];
double low[N];
double dis[N][N], dp[N][N];
int n, m, num;
double sum;
void init()
{
sum = 0;
num = 0;
memset(flag, 0, sizeof(flag));
memset(vis, 0, sizeof(vis));
memset(head, -1, sizeof(head));
memset(dp, 0, sizeof(dp));
}
double Dis(int x0, int y0, int x1, int y1)
{
return sqrt(1.0*(x0-x1)*(x0-x1) + 1.0*(y0-y1)*(y0-y1));
}
void add(int s, int t)
{
f[num].to = t;
f[num].next = head[s];
head[s] = num ++;
}
void prime()
{
for(int i = 1; i <= n; i++)
{
low[i] = dis[1][i];
pre[i] = 1;
}
flag[1] = 1;
for(int i = 1; i < n; i++)
{
double Min = INF;
int v;
for(int j = 1; j <= n; j++)
{
if(!flag[j] && Min > low[j])
{
v = j;
Min = low[j];
}
}
sum += Min;
vis[pre[v]][v] = vis[v][pre[v]] = 1;
add(v, pre[v]);
add(pre[v], v);
flag[v] = 1;
for(int j = 1; j <= n; j++)
{
if(!flag[j] && low[j] > dis[v][j])
{
low[j] = dis[v][j];
pre[j] = v;
}
}
}
}
double dfs(int cur, int u, int fa) //用cur更新cur點所在的子樹和另外子樹的最短距離
{
double ans = INF;
for(int i = head[u]; ~i; i = f[i].next) //沿著生成樹的邊遍歷
{
if(f[i].to == fa)
continue;
double tmp = dfs(cur, f[i].to, u); //用cur更新的以當前邊為割邊的兩個子樹最短距離
ans = min(tmp, ans); //以(fa,u)為割邊的2個子樹的最短距離
dp[u][f[i].to] = dp[f[i].to][u] = min(tmp, dp[u][f[i].to]);
}
if(cur != fa) //生成樹邊不更新
ans = min(ans, dis[cur][u]);
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d %d",&n, &m);
for(int i = 1; i <= n; i++) scanf("%d %d",&p[i].x, &p[i].y);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
{
dp[i][j] = dp[j][i] = INF;
if(i == j)
{
dis[i][j] = 0.0;
continue;
}
dis[i][j] = dis[j][i] = Dis(p[i].x, p[i].y, p[j].x, p[j].y);
}
}
prime();
double ans = sum;
for(int i = 0; i < n; i++) dfs(i, i, -1);
for(int i = 2; i <= n; i++)
{
for(int j = 2; j < i; j++)
{
if(!vis[i][j]) continue;
ans = max(ans, sum-dis[i][j]+dp[i][j]);
}
}
printf("%.2lf\n",ans*m);
}
return 0;
}
相關文章
- 2013成都站F題||hdu4786 並查集 生成樹並查集
- hdu 3874 樹狀陣列陣列
- 線段樹 transformation——hdu 4578ORM
- 小程式 canvas 生成海報 一次搞掂Canvas
- hdu 1754 I Hate It (線段樹)
- hdu 5147 樹狀陣列陣列
- hdu 4836 The Query on the Tree(線段樹or樹狀陣列)陣列
- 生成樹協議與多生成樹協議協議
- 生成樹Toolkit
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- Transformation HDU - 4578線段樹綜合操作ORM
- hdu 1754 【線段樹/RMQ】I Hate ItMQ
- hdu 3973 字串hash+線段樹字串
- HDU3264 Open-air shopping malls (圓交+二分)AI
- STP生成樹協議和MSTP多生成樹協議協議
- 小樹
- 最小生成樹
- HDU 1754 I Hate It 線段樹入門
- HDU 5326 Work (基礎樹形dp)
- hdu 4123 樹形DP+RMQMQ
- Matlab生成Kruskal最小生成樹Matlab
- POJ 2831 Can We Build This One:次小生成樹【N^2預處理】UI
- STP(生成樹協議)協議
- STP生成樹協議協議
- 生成樹演算法演算法
- 最小度限制生成樹
- 【模板】最小生成樹
- hdu4325 樹狀陣列+離散化陣列
- hdu4288 離線處理線段樹
- hdu 4368 樹狀陣列 離線維護陣列
- HDU6035-Colorful Tree-虛樹思想
- 【KMP求字串匹配次數】 hdu 1686KMP字串匹配
- hdu4417 樹狀陣列(求指定區間比指定數小的數的個數)陣列
- HDU 2662 Coin && HDU 1792 A New Change Problem (互質數最大不能生成數)
- No AirAI
- HDU 4704 Sum (隔板原理 + 費馬小定理)
- HDU 1754 I Hate It (線段樹 區間最值)
- HDU 2689 Sort it【樹狀陣列求逆序對】陣列