Catalog
Two, the actual battle of Kruskal
Force buckle 1584. Minimum cost of connecting all points
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 the answer is 150*sqrt(2)=212.13
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; } };