511 words
3 minutes
P1364 Hospital Placement Solution

Problem Description#

Find a point such that the total distance from all other points to it is minimized.

The calculation method for the total distance is: the sum of (each point’s population multiplied by its distance to the target point).

Note! This problem has no edge weights! Only node weights (I stumbled here the first time [facepalm]).

Approach#

There are two methods: brute force and rerooting DP.

The brute force method is straightforward. Since nn is small, directly traverse each node from 11 to nn as the root, perform a DFS to calculate the total distance, and take the minimum value.

Rerooting DP involves first performing a DFS to calculate the total distance with node 11 as the root, then performing another DFS to calculate the total distance with other nodes as the root, and finally taking the minimum value.

So, what is the state transition equation?

Look at the graph in the problem. If the hospital is moved to node 33, doesn’t it mean that nodes 11 and 22 on the left have to travel farther, while nodes 33, 44, and 55 on the right have to travel less?

Thus, the state transition equation can easily be derived as:

f[v]=f[u]+size[1]size[v]size[v]f[v] = f[u] + size[1] - size[v] - size[v]

Done!

Code#

// Brute force solution
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector <int> wth[105];
int ans = 1e9, cnt[105], hz[105];
int a[105];
void dfs(int now, int f, int dep, int rt)
{
cnt[now] = hz[now];
a[rt] += hz[now] * dep;
for(auto v : wth[now])
{
if(v == f)
{
continue;
}
dfs(v, now, dep + 1, rt);
cnt[now] += cnt[v];
}
}
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
int u, v, w;
cin >> w >> u >> v;
hz[i] = w;
if(u != 0)
{
wth[i].push_back(u);
wth[u].push_back(i);
}
if(v != 0)
{
wth[i].push_back(v);
wth[v].push_back(i);
}
}
for(int i = 1; i <= n; i++)
{
dfs(i, 0, 0, i);
ans = min(ans, a[i]);
}
cout << ans;
return 0;
}
Plain and Simple Dividing “Word”#
// Rerooting DP solution
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector <int> wth[105];
int ans = 1e9, cnt[105], hz[105];
int a[105];
void dfs(int now, int f, int dep)
{
cnt[now] = hz[now];
a[1] += hz[now] * dep;
for(auto v : wth[now])
{
if(v == f)
{
continue;
}
dfs(v, now, dep + 1);
cnt[now] += cnt[v];
}
}
void dfs2(int u, int f)
{
if(u != 1)
{
a[u] = a[f] + (cnt[1] - cnt[u]) - cnt[u];
}
ans = min(ans, a[u]);
for(auto v : wth[u])
{
if(v == f)
{
continue;
}
dfs2(v, u);
}
}
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
int u, v, w;
cin >> w >> u >> v;
hz[i] = w;
if(u != 0)
{
wth[i].push_back(u);
wth[u].push_back(i);
}
if(v != 0)
{
wth[i].push_back(v);
wth[v].push_back(i);
}
}
dfs(1, 0, 0);
dfs2(1, 0);
cout << ans;
return 0;
}

This is my first time writing a solution. If there are any inaccuracies, please feel free to point them out =D

P1364 Hospital Placement Solution
https://featured.fanzhuo.xyz/posts/p1364/
Author
Fanzhuo
Published at
2024-12-14
License
CC BY-NC-SA 4.0