# minimum spanning tree

Keywords: Algorithm new

Catalog

One, Kruskal

Two, the actual battle of Kruskal

POJ 2349 Arctic Network

Force buckle   1584. Minimum cost of connecting all points

Three, Prim

Fourth, Prim Actual Warfare

Force buckle   1584. Minimum cost of connecting all points

# One, Kruskal

Algorithmic ideas:

Start to think of each point as a separate tree. Each time you select the shortest side of the edge that is not made up of two points on a tree, connect the two points and merge the two trees into a single tree.

One side at a time until all the points are connected into a tree.

Template code:

```const int N = 1000; //Maximum number of points
int en; //Number of points
// TODO records point information with an array or vector s, id starting at 0

int fa[N];
int find(int x)	//Find Ancestors
{
if (fa[x] == x)return x;
return fa[x] = find(fa[x]);
}
void merge(int i, int j)
{
fa[find(i)] = j;
}
bool inSameSet(int i, int j)
{
return find(i) == find(j);
}

struct Edge
{
int a;//Endpoint id
int b;//Endpoint id
int dist;
};

bool cmp(Edge a, Edge b)
{
return a.dist < b.dist;
}

int getLen(int i, int j) // Calculate the distance between two points with id i and j
{
return 0; // TODO is modified as appropriate
}
vector<Edge> getEdge() // Get all edges
{
// TODO is modified as appropriate
vector<Edge> v;
for (int i = 0; i < en; i++)for (int j = i + 1; j < en; j++) {
Edge e = { i,j,getLen(i,j) };
v.push_back(e);
}
return v;
}

//Calculates the minimum spanning tree, sorting the results from smallest to largest edges
vector<pair<int, int>> minCostConnectPoints()
{
vector<Edge> v = getEdge();
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < en; i++)fa[i] = i;
vector<pair<int, int>>ans;
for (int i = 0, j = 0; j < en - 1; i++)
{
if (inSameSet(v[i].a, v[i].b))continue;
merge(v[i].a, v[i].b);
ans.push_back(make_pair(v[i].a, v[i].b));
j++;
}
return ans;
}```

Time complexity: O (ElogE), where E is the number of edges.

# Two, the actual battle of Kruskal

## POJ 2349 Arctic Network

Title:

Description

The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel.
Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts.

Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.

Input

The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000).

Output

For each case, output should consist of a single line giving the minimum D required to connect the network. Output should be specified to 2 decimal points.

Sample Input
1
2 4
0 100
0 300
0 600
150 750

Sample Output

212.13

This title means that there are p sites, of which s can be connected by satellites. (Satellites are not sites)

There are still p-s sites left, so you need to connect them all with p-s straight lines.

Find at least how long the longest straight segment is.

For example, in this topic, we select 0,300 and 0,600 satellites to connect.

0,100 A segment with 200 can connect 0,300,150,750 A segment with 150*sqrt(2) can connect 0,600

So, what this title means is, give you the coordinates of p points, all of which are connected.

Select a spanning tree, where the larger s-1 edge can be replaced by satellites, and the longest of the smaller p-s edges, at least how long?

This is obviously the Kruskal algorithm.

Code:

```#include<iostream>
#include<vector>
#include<stdio.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;

const int N = 500; //Maximum number of points
int en; //Number of points
// Record point information with an array or vector s, id starting at 0
struct node
{
int x;
int y;
};
node nod[N];

int fa[N];
int find(int x)	//Find Ancestors
{
if (fa[x] == x)return x;
return fa[x] = find(fa[x]);
}
void merge(int i, int j)
{
fa[find(i)] = j;
}
bool inSameSet(int i, int j)
{
return find(i) == find(j);
}

struct Edge
{
int a;//Endpoint id
int b;//Endpoint id
int dist;
};

bool cmp(Edge a, Edge b)
{
return a.dist < b.dist;
}

int getLen(int i, int j) // Calculate the distance between two points with id i and j
{
return (nod[j].x - nod[i].x) * (nod[j].x - nod[i].x)
+ (nod[j].y - nod[i].y) * (nod[j].y - nod[i].y);
}
vector<Edge> getEdge() // Get all edges
{
// TODO is modified as appropriate
vector<Edge> v;
for (int i = 0; i < en; i++)for (int j = i + 1; j < en; j++) {
Edge e = { i,j,getLen(i,j) };
v.push_back(e);
}
return v;
}

//Calculates the minimum spanning tree, sorting the results from smallest to largest edges
vector<pair<int, int>> minCostConnectPoints()
{
vector<Edge> v = getEdge();
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < en; i++)fa[i] = i;
vector<pair<int, int>>ans;
for (int i = 0, j = 0; j < en - 1; i++)
{
if (inSameSet(v[i].a, v[i].b))continue;
merge(v[i].a, v[i].b);
ans.push_back(make_pair(v[i].a, v[i].b));
j++;
}
return ans;
}

int main()
{
int t, s;
cin >> t;
for (int i = 0; i < t; i++)
{
cin >> s >> en;
for (int j = 0; j < en; j++)
{
cin >> nod[j].x >> nod[j].y;
}
vector<pair<int, int>> v = minCostConnectPoints();
pair<int, int> pa = v[en - s - 1];
double c = 1.0;
cout << fixed << setprecision(2) << sqrt(c * getLen(pa.first, pa.second)) << endl;
}
return 0;
}```

## Force buckle   1584. Minimum cost of connecting all points

Give you a point   Array representing points on the 2D plane, where   points[i] = [xi, yi]  .

Connection Point   [xi, yi] and points   [xj, yj]   The cost is the Manhattan distance between them  : | xi - xj| + |yi - yj|  ， among  | val|   Express   val   Absolute value.

Please return the minimum total cost of all connections. Only between any two points and only   All points are considered connected when there is a simple path.

Example 1:

Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
Output: 20
Explanation:

We can get a minimum total cost of 20 for connecting all points as shown in the figure above.
Notice that only one path between any two points arrives at each other.
Example 2:

Input: points = [[3,12],[-2,5],[-4,1]]
Output: 18
Example 3:

Input: points = [[0,0],[1,1],[1,0],[-1,1]]
Output: 4
Example 4:

Input: points = [[-1000000,-1000000],[1000000,1000000]]
Output: 4000000
Example 5:

Input: points = [[0,0]]
Output: 0

Tips:

1 <= points.length <= 1000
-106 <= xi, yi <= 106
All Points   (xi, yi)   Two are different.

```const int N = 1000; //Maximum number of points
int en; //Number of points
// TODO records point information with an array or vector s, id starting at 0
vector<vector<int>>p;

int fa[N];
int find(int x)	//Find Ancestors
{
if (fa[x] == x)return x;
return fa[x] = find(fa[x]);
}
void merge(int i, int j)
{
fa[find(i)] = j;
}
bool inSameSet(int i, int j)
{
return find(i) == find(j);
}

struct Edge
{
int a;//Endpoint id
int b;//Endpoint id
int dist;
};

bool cmp(Edge a, Edge b)
{
return a.dist < b.dist;
}

int getLen(int i, int j) // Calculate the distance between two points with id i and j
{
return abs(p[i][0] - p[j][0]) + abs(p[i][1] - p[j][1]);
}
vector<Edge> getEdge() // Get all edges
{
// TODO is modified as appropriate
vector<Edge> v;
for (int i = 0; i < en; i++)for (int j = i + 1; j < en; j++) {
Edge e = { i,j,getLen(i,j) };
v.push_back(e);
}
return v;
}

//Calculates the minimum spanning tree, sorting the results from smallest to largest edges
vector<pair<int, int>> minCostConnectPoints2()
{
vector<Edge> v = getEdge();
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < en; i++)fa[i] = i;
vector<pair<int, int>>ans;
for (int i = 0, j = 0; j < en - 1; i++)
{
if (inSameSet(v[i].a, v[i].b))continue;
merge(v[i].a, v[i].b);
ans.push_back(make_pair(v[i].a, v[i].b));
j++;
}
return ans;
}

class Solution {
public:
int minCostConnectPoints(vector<vector<int>>& points) {
p = points;
en = p.size();
vector<pair<int, int>> v = minCostConnectPoints2();
int ans = 0;
for (pair<int, int> vi : v) {
ans += getLen(vi.first, vi.second);
}
return ans;
}
};```

# Three, Prim

Prim is almost identical to Dijkstra in that the difference is only in the total path length from each point of the Dijkstra's distance to the starting point, whereas Prim's distance is the distance from each point to the nearest point.

Template code:

```const int N = 1000; //Maximum number of points
int en; //Number of points
// TODO records point information with an array or vector s, id starting at 0
vector<vector<int>>p;
bool visit_[N];
int minLen[N];

int getLen(int i, int j) // Calculate the distance between two points with id i and j
{
return 0; // TODO is modified as appropriate
}

int getStartId()
{
int m = INT_MAX;
int ans = 0;
for (int i = 0; i < en; i++) {
for (int j = 0; j < en; j++) {
if (i != j && m > getLen(i, j)) {
m = getLen(i, j);
ans = i;
}
}
}
return ans;
}
void init()
{
for (int i = 0; i < en; i++) {
minLen[i] = INT_MAX;
visit_[i] = false;
}
minLen[getStartId()] = INT_MIN;
}

int getId()
{
int m= INT_MAX;
int ans = 0;
for (int i = 0; i < en; i++) {
if (!visit_[i] && m > minLen[i]) {
m = minLen[i];
ans = i;
}
}
return ans;
}
void fresh(int id)
{
for (int i = 0; i < en; i++) {
if (!visit_[i])minLen[i] = min(minLen[i], getLen(i, id));
}
}

//Calculates the minimum spanning tree, sorting the results from smallest to largest edges
vector<pair<int, int>> minCostConnectPoints()
{
init();
vector<pair<int, int>>ans;
for (int i = 0; i < en; i++) {
int id = getId();
for (int j = 0; j < en; j++) {
if (visit_[j] && getLen(id, j) == minLen[id]) {
ans.push_back(make_pair(id, j));
break;
}
}
visit_[id] = true;
fresh(id);
}
return ans;
}```

Time complexity: O (V^2), where V is the number of points.

# Fourth, Prim Actual Warfare

## Force buckle   1584. Minimum cost of connecting all points

The title is the same as above

```const int N = 1000; //Maximum number of points
int en; //Number of points
// TODO records point information with an array or vector s, id starting at 0
vector<vector<int>>p;
bool visit_[N];
int minLen[N];

int getLen(int i, int j) // Calculate the distance between two points with id i and j
{
return abs(p[i][0] - p[j][0]) + abs(p[i][1] - p[j][1]);
}

int getStartId()
{
int m = INT_MAX;
int ans = 0;
for (int i = 0; i < en; i++) {
for (int j = 0; j < en; j++) {
if (i != j && m > getLen(i, j)) {
m = getLen(i, j);
ans = i;
}
}
}
return ans;
}
void init()
{
for (int i = 0; i < en; i++) {
minLen[i] = INT_MAX;
visit_[i] = false;
}
minLen[getStartId()] = INT_MIN;
}

int getId()
{
int m= INT_MAX;
int ans = 0;
for (int i = 0; i < en; i++) {
if (!visit_[i] && m > minLen[i]) {
m = minLen[i];
ans = i;
}
}
return ans;
}
void fresh(int id)
{
for (int i = 0; i < en; i++) {
if (!visit_[i])minLen[i] = min(minLen[i], getLen(i, id));
}
}

//Calculates the minimum spanning tree, sorting the results from smallest to largest edges
vector<pair<int, int>> minCostConnectPoints2()
{
init();
vector<pair<int, int>>ans;
for (int i = 0; i < en; i++) {
int id = getId();
for (int j = 0; j < en; j++) {
if (visit_[j] && getLen(id, j) == minLen[id]) {
ans.push_back(make_pair(id, j));
break;
}
}
visit_[id] = true;
fresh(id);
}
return ans;
}

class Solution {
public:
int minCostConnectPoints(vector<vector<int>>& points) {
p = points;
en = p.size();
vector<pair<int, int>> v = minCostConnectPoints2();
int ans = 0;
for (pair<int, int> vi : v) {
ans += getLen(vi.first, vi.second);
}
return ans;
}
};```

Posted by glassroof on Wed, 27 Oct 2021 10:33:59 -0700