【kuangbin带你飞】 MST专题
唉,被班级合唱和复变考试搞得心力交瘁。新算法学不进去,更新下吧
A - Til the Cows Come Home
The Head Elder of the tropical island of Lagrishan has a
problem. A burst of foreign aid money was spent on extra roads between
villages some years ago. But the jungle overtakes roads relentlessly, so
the large road network is too expensive to maintain. The Council of
Elders must choose to stop maintaining some roads. The map above on the
left shows all the roads in use now and the cost in aacms per month to
maintain them. Of course there needs to be some way to get between all
the villages on maintained roads, even if the route is not as short as
before. The Chief Elder would like to tell the Council of Elders what
would be the smallest amount they could spend in aacms per month to
maintain roads that would connect all the villages. The villages are
labeled A through I in the maps above. The map on the right shows the
roads that could be maintained most cheaply, for 216 aacms per month.
Your task is to write a program that will solve such problems.
Input
line containing only 0. Each data set starts with a line containing only
a number n, which is the number of villages, 1 < n < 27, and the
villages are labeled with the first n letters of the alphabet,
capitalized. Each data set is completed with n-1 lines that start with
village labels in alphabetical order. There is no line for the last
village. Each line for a village starts with the village label followed
by a number, k, of roads from this village to villages with labels later
in the alphabet. If k is greater than 0, the line continues with data
for each of the k roads. The data for each road is the village label for
the other end of the road followed by the monthly maintenance cost in
aacms for the road. Maintenance costs will be positive integers less
than 100. All data fields in the row are separated by single blanks. The
road network will always allow travel between all the villages. The
network will never have more than 75 roads. No village will have more
than 15 roads going to other villages (before or after in the alphabet).
In the sample input below, the first data set goes with the map above.
Output
cost in aacms per month to maintain a road system that connect all the
villages. Caution: A brute force solution that examines every possible
set of roads will not finish within the one minute time limit.
Sample Input
- 9
- A 2 B 12 I 25
- B 3 C 10 H 40 I 8
- C 2 D 18 G 55
- D 1 E 44
- E 2 F 60 G 38
- F 0
- G 1 H 35
- H 1 I 35
- 3
- A 2 B 10 C 40
- B 1 C 20
- 0
Sample Output
- 216
- 30
- 思路:把字母转换成节点编号套下板子就可以了
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = ;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
///初始化MST为空
///初始化连通分量,让每个点自成一个独立的连通分量
///for(int i = 0; i < m; i++) {
/// if(e[i].u 和 e[i].v 不在同一个连通分量) {
/// 把边e[i]加入MST
/// 合并e[i].u 和 e[i].v 所在的连通分量
/// }
///}- int fa[],n,m,ans,eu,ev,cnt,t;
- struct node{
- int u, v, w;
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void kruskal()
- {
- sort(e, e+m, cmp);
- for(int i = ; i < m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- /*if(++cnt == n-1) {
- break;
- }*/
- }
- }
- int main()
- {
- while(scanf("%d",&n)) {
- if(!n) break;
- for(int i = ; i <= ; i++) {
- fa[i] = i;
- }
- int t = n-;
- m = ;
- ans = ;
- while(t--) {
- char ch;
- int num;
- cin >> ch >> num;
- while(num--) {
- char vge;
- int cost;
- cin >> vge >> cost;
- e[m].u = ch-;
- e[m].v = vge-;
- e[m].w = cost;
- m++;
- }
- }
- /*for(int i = 0; i < m; i++) {
- printf("e[%d].u:%d e[%d].v:%d e[%d].w:%d\n",i,e[i].u,i,e[i].v,i,e[i].w);
- }*/
- kruskal();
- printf("%d\n",ans);
- }
- return ;
- }
B - Networking
Your task is to design the network for the area, so that
there is a connection (direct or indirect) between every two points
(i.e., all the points are interconnected, but not necessarily by a
direct cable), and that the total length of the used cable is minimal.
Input
defines one required network. The first line of the set contains two
integers: the first defines the number P of the given points, and the
second the number R of given routes between the points. The following R
lines define the given routes between the points, each giving three
integer numbers: the first two numbers identify the points, and the
third gives the length of the route. The numbers are separated with
white spaces. A data set giving only one number P=0 denotes the end of
the input. The data sets are separated with an empty line.
The maximal number of points is 50. The maximal length of a
given route is 100. The number of possible routes is unlimited. The
nodes are identified with integers between 1 and P (inclusive). The
routes between two points i and j may be given as i j or as j i.
Output
the total length of the cable used for the entire designed network.
Sample Input
- 1 0
- 2 3
- 1 2 37
- 2 1 17
- 1 2 68
- 3 7
- 1 2 19
- 2 3 11
- 3 1 7
- 1 3 5
- 2 3 89
- 3 1 91
- 1 2 32
- 5 7
- 1 2 5
- 2 3 7
- 2 4 8
- 4 5 11
- 3 5 10
- 1 5 6
- 4 2 12
- 0
Sample Output
- 0
- 17
- 16
- 26
- 思路:板子题
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt;
- struct node{
- int u, v, w;
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- bool unite(int r1, int r2)
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int n, int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- //printf("!!! i:%d n:%d m:%d\n",i,n,m);
- if(unite(e[i].u,e[i].v)) {
- cnt++;
- ans += e[i].w;
- //printf("ans:%d\n",ans);
- }
- if(cnt == n-) {
- break;
- }
- }
- }
- int main()
- {
- while(scanf("%d",&n) && n) {
- scanf("%d",&m);
- init(n);
- for(int i = ; i <= m; i++) {
- scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
- }
- kruskal(n,m);
- printf("%d\n",ans);
- }
- return ;
- }
C - Building a Space Station
The space station is made up with a number of units, called
cells. All cells are sphere-shaped, but their sizes are not necessarily
uniform. Each cell is fixed at its predetermined position shortly after
the station is successfully put into its orbit. It is quite strange that
two cells may be touching each other, or even may be overlapping. In an
extreme case, a cell may be totally enclosing another one. I do not
know how such arrangements are possible.
All the cells must be connected, since crew members should be
able to walk from any cell to any other cell. They can walk from a cell
A to another cell B, if, (1) A and B are touching each other or
overlapping, (2) A and B are connected by a `corridor', or (3) there is a
cell C such that walking from A to C, and also from B to C are both
possible. Note that the condition (3) should be interpreted
transitively.
You are expected to design a configuration, namely, which
pairs of cells are to be connected with corridors. There is some freedom
in the corridor configuration. For example, if there are three cells A,
B and C, not touching nor overlapping each other, at least three plans
are possible in order to connect all three cells. The first is to build
corridors A-B and A-C, the second B-C and B-A, the third C-A and C-B.
The cost of building a corridor is proportional to its length.
Therefore, you should choose a plan with the shortest total length of
the corridors.
You can ignore the width of a corridor. A corridor is built
between points on two cells' surfaces. It can be made arbitrarily long,
but of course the shortest one is chosen. Even if two corridors A-B and
C-D intersect in space, they are not considered to form a connection
path between (for example) A and C. In other words, you may consider
that two corridors never intersect.
Input
n
x1 y1 z1 r1
x2 y2 z2 r2
...
xn yn zn rn
The first line of a data set contains an integer n, which is the number of cells. n is positive, and does not exceed 100.
The following n lines are descriptions of cells. Four values
in a line are x-, y- and z-coordinates of the center, and radius (called
r in the rest of the problem) of the sphere, in this order. Each value
is given by a decimal fraction, with 3 digits after the decimal point.
Values are separated by a space character.
Each of x, y, z and r is positive and is less than 100.0.
The end of the input is indicated by a line containing a zero.
Output
should be printed, each in a separate line. The printed values should
have 3 digits after the decimal point. They may not have an error
greater than 0.001.
Note that if no corridors are necessary, that is, if all the
cells are connected without corridors, the shortest total length of the
corridors is 0.000.
Sample Input
- 3
- 10.000 10.000 50.000 10.000
- 40.000 10.000 50.000 10.000
- 40.000 40.000 50.000 10.000
- 2
- 30.000 30.000 30.000 20.000
- 40.000 40.000 40.000 20.000
- 5
- 5.729 15.143 3.996 25.837
- 6.013 14.372 4.818 10.671
- 80.115 63.292 84.477 15.120
- 64.095 80.924 70.029 14.881
- 39.472 85.116 71.369 5.553
- 0
Sample Output
- 20.000
- 0.000
- 73.834
思路:把所有点先存起来,算出每个点之间的距离。
注意:POJ这个东西得double,G++和C++轮着交
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <cmath>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m;
- double ans;
- int eu,ev,cnt;
- struct node {
- int u,v;
- double w;
- }e[maxn];
- struct Node {
- double x,y,z,r;
- }a[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- bool unite(int r1, int r2)
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- //if(++cnt == n-1) {
- //break;
- //}
- }
- }
- int main()
- {
- while(scanf("%d",&n) && n) {
- for(int i = ; i <= n; i++) {
- scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z,&a[i].r);
- }
- //int u,v,w;
- int num = ;
- for(int i = ; i < n; i++) {
- for(int j = i+; j <= n; j++) {
- e[num].u = i, e[num].v = j;
- double temp;
- temp = sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)+(a[i].z-a[j].z)*(a[i].z-a[j].z))- a[i].r - a[j].r;
- temp = max(0.0,temp);
- e[num].w = temp;
- num++;
- }
- }
- num--;
- init(n);
- kruskal(num);
- printf("%.3lf\n",ans);
- }
- return ;
- }
D - Constructing Roads
We know that there are already some roads between some
villages and your job is the build some roads such that all the villages
are connect and the length of all the roads built is minimum.
Input
the number of villages. Then come N lines, the i-th of which contains N
integers, and the j-th of these N integers is the distance (the distance
should be an integer within [1, 1000]) between village i and village j.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2).
Then come Q lines, each line contains two integers a and b (1 <= a
< b <= N), which means the road between village a and village b
has been built.
Output
of all the roads to be built such that all the villages are connected,
and this value is minimum.
Sample Input
- 3
- 0 990 692
- 990 0 179
- 692 179 0
- 1
- 1 2
Sample Output
- 179
- 思路:存点算间距,给出的已连通的直接让他们距离为0就可以了
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt;
- struct node{
- int u, v, w;
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- if(++cnt == n-) {
- break;
- }
- }
- }
- int main()
- {
- while(scanf("%d",&n)!=EOF) {
- int num = ;
- int temp;
- for(int i = ; i <= n; i++) {
- for(int j = ; j <= n; j++) {
- cin >> temp;
- if(i == j) continue;
- e[num].u = i, e[num].v = j;
- e[num].w = temp;
- num++;
- }
- }
- num--;
- int q;
- cin >> q;
- while(q--) {
- int x,y;
- cin >> x >> y;
- for(int i = ; i <= num; i++) {
- if(e[i].u == x && e[i].v == y) {
- e[i].w = ;
- }
- if(e[i].u == y && e[i].v == x) {
- e[i].w = ;
- }
- }
- }
- init(n);
- kruskal(num);
- printf("%d\n",ans);
- }
- return ;
- }
E - Truck History
Today, ACM is rich enough to pay historians to study its
history. One thing historians tried to find out is so called derivation
plan -- i.e. how the truck types were derived. They defined the distance
of truck types as the number of positions with different letters in
truck type codes. They also assumed that each truck type was derived
from exactly one other truck type (except for the first truck type which
was not derived from any other type). The quality of a derivation plan
was then defined as
1/Σ(to,td)d(to,td)
where the sum goes over all pairs of types in the derivation plan such that t
o is the original type and t
d the type derived from it and d(t
o,t
d) is the distance of the types.
Since historians failed, you are to write a program to help
them. Given the codes of truck types, your program should find the
highest possible quality of a derivation plan.
Input
with a line containing the number of truck types, N, 2 <= N <= 2
000. Each of the following N lines of input contains one truck type code
(a string of seven lowercase letters). You may assume that the codes
uniquely describe the trucks, i.e., no two of these N lines are the
same. The input is terminated with zero at the place of number of truck
types.
Output
highest possible quality is 1/Q.", where 1/Q is the quality of the best
derivation plan.
Sample Input
- 4
- aaaaaaa
- baaaaaa
- abaaaaa
- aabaaaa
- 0
Sample Output
- The highest possible quality is 1/3.
思路:题意有点难以理解,模拟下给出的公式就知道什么意思了
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = 6e6+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt;
- struct node {
- int u, v, w;
- }e[maxn];
- struct Node {
- char s[];
- }a[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- if(++cnt == n-) {
- break;
- }
- }
- }
- int main()
- {
- while(scanf("%d",&n) && n) {
- for(int i = ; i <= n; i++) {
- cin >> a[i].s;
- //printf("len:%d\n",a[i].s.length());
- }
- int num = ;
- for(int i = ; i < n; i++) {
- for(int j = i+; j <= n; j++) {
- e[num].u = i, e[num].v = j;
- int temp = ;
- for(int k = ; k < ; k++) {
- if(a[i].s[k] != a[j].s[k])
- temp++;
- }
- e[num].w = temp;
- num++;
- }
- }
- num--;
- init(n);
- kruskal(num);
- printf("The highest possible quality is 1/%d.\n",ans);
- }
- return ;
- }
F - Arctic Network
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
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
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
思路:存点算距离
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <cmath>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt;
- struct node{
- int u, v;
- double w;
- }e[maxn];
- struct Node {
- double x,y;
- }a[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int n,int s,int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- //printf("cnt:%d n-s:%d\n",cnt+1,n-s);
- if(++cnt == n-s) {
- printf("%.2lf\n",e[i].w);
- break;
- }
- }
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--) {
- int s,n;
- scanf("%d %d",&s,&n);
- for(int i = ; i <= n; i++) {
- scanf("%lf %lf",&a[i].x,&a[i].y);
- }
- int num = ;
- for(int i = ; i <= n; i++) {
- for(int j = i+; j <= n; j++) {
- e[num].u = i, e[num].v = j;
- e[num].w = sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
- num++;
- }
- }
- /*for(int i = 1; i <= num; i++) {
- printf("e[%d]:%lf\n",i,e[i].w);
- }*/
- num--;
- init(n);
- kruskal(n,s,num);
- }
- return ;
- }
G - Highways
Flatopian towns are numbered from 1 to N and town i has a
position given by the Cartesian coordinates (xi, yi). Each highway
connects exaclty two towns. All highways (both the original ones and the
ones that are to be built) follow straight lines, and thus their length
is equal to Cartesian distance between towns. All highways can be used
in both directions. Highways can freely cross each other, but a driver
can only switch between highways at a town that is located at the end of
both highways.
The Flatopian government wants to minimize the cost of
building new highways. However, they want to guarantee that every town
is highway-reachable from every other town. Since Flatopia is so flat,
the cost of a highway is always proportional to its length. Thus, the
least expensive highway system will be the one that minimizes the total
highways length.
Input
towns in the country, and the second part describes all of the highways
that have already been built.
The first line of the input file contains a single integer N
(1 <= N <= 750), representing the number of towns. The next N
lines each contain two integers, xi and yi separated by a space. These
values give the coordinates of i
th town (for i from 1 to N). Coordinates will have an absolute value no greater than 10000. Every town has a unique location.
The next line contains a single integer M (0 <= M <=
1000), representing the number of existing highways. The next M lines
each contain a pair of integers separated by a space. These two integers
give a pair of town numbers which are already connected by a highway.
Each pair of towns is connected by at most one highway.
Output
should be built in order to connect all towns with minimal possible
total length of new highways. Each highway should be presented by
printing town numbers that this highway connects, separated by a space.
If no new highways need to be built (all towns are already
connected), then the output file should be created but it should be
empty.
Sample Input
- 9
- 1 5
- 0 0
- 3 2
- 4 5
- 5 1
- 0 4
- 5 2
- 1 2
- 5 3
- 3
- 1 3
- 9 7
- 1 2
Sample Output
- 1 6
- 3 7
- 4 9
- 5 7
- 8 3
思路:多组输入wa,存点计算各点之间的距离,然后kruskal
- #include<cstdio>
- #include<iostream>
- #include<algorithm>
- #include<string>
- #include<cstring>
- using namespace std;
- const int maxn = ;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt;
- struct Node
- {
- int x, y;
- }a[maxn];
- void init(int n)
- {
- cnt = ;
- ans = ;
- for (int i = ; i <= n; i++)
- fa[i] = i;
- }
- struct node
- {
- int u, v, w;
- bool operator < (const node& A) const
- {
- return w < A.w;
- }
- }edge[maxn * maxn];
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal()
- {
- sort(edge, edge + m);
- for (int i = ; i < m; i++)
- {
- int u = edge[i].u, v = edge[i].v, w = edge[i].w;
- if (unite(u, v))
- {
- printf("%d %d\n", u, v);
- cnt++;
- if (cnt == n - ) break;
- }
- }
- }
- int main()
- {
- scanf("%d", &n);
- {
- m = ;
- for (int i = ; i <= n; i++)
- {
- scanf("%d%d", &a[i].x, &a[i].y);
- for (int j = ; j < i; j++)
- {
- edge[m].u = i;
- edge[m].v = j;
- edge[m++].w = (a[i].x - a[j].x) * (a[i].x - a[j].x) +
- (a[i].y - a[j].y) * (a[i].y - a[j].y);
- }
- }
- int Q;
- scanf("%d", &Q);
- while (Q--)
- {
- int a, b;
- scanf("%d%d", &a, &b);
- if (unite(a, b)) cnt++;
- }
- kruskal();
- }
- return ;
- }
H - Agri-Net
Farmer John ordered a high speed connection for his farm and
is going to share his connectivity with the other farmers. To minimize
cost, he wants to lay the minimum amount of optical fiber to connect his
farm to all the other farms.
Given a list of how much fiber it takes to connect each pair
of farms, you must find the minimum amount of fiber needed to connect
them all together. Each farm must connect to some other farm such that a
packet can flow from any one farm to any other farm.
The distance between any two farms will not exceed 100,000.
Input
contains the number of farms, N (3 <= N <= 100). The following
lines contain the N x N conectivity matrix, where each element shows the
distance from on farm to another. Logically, they are N lines of N
space-separated integers. Physically, they are limited in length to 80
characters, so some lines continue onto others. Of course, the diagonal
will be 0, since the distance from farm i to itself is not interesting
for this problem.
Output
the minimum length of fiber required to connect the entire set of farms.
Sample Input
- 4
- 0 4 9 21
- 4 0 8 17
- 9 8 0 16
- 21 17 16 0
Sample Output
- 28
- 思路:存点计算各点间距,然后kruskal
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = 2e5+;
- typedef long long LL;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m;
- LL ans;
- int eu,ev,cnt;
- struct node{
- int u, v, w;
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int n, int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- if(++cnt == n-) {
- break;
- }
- }
- }
- int main()
- {
- while(scanf("%d",&n)!=EOF) {
- int num = ;
- for(int i = ; i <= n; i++) {
- for(int j = ; j <= n; j++) {
- int temp;
- scanf("%d",&temp);
- if(i != j) {
- e[num].w = temp;
- e[num].u = i, e[num].v = j;
- num++;
- }
- }
- }
- num--;
- init(n);
- kruskal(n,num);
- printf("%lld\n",ans);
- }
- return ;
- }
I - Borg Maze
Your task is to help the Borg (yes, really) by developing a
program which helps the Borg to estimate the minimal cost of scanning a
maze for the assimilation of aliens hiding in the maze, by moving in
north, west, east, and south steps. The tricky thing is that the
beginning of the search is conducted by a large group of over 100
individuals. Whenever an alien is assimilated, or at the beginning of
the search, the group may split in two or more groups (but their
consciousness is still collective.). The cost of searching a maze is
definied as the total distance covered by all the groups involved in the
search together. That is, if the original group walks five steps, then
splits into two groups each walking three steps, the total distance is
11=5+3+3.
Input
giving the number of test cases in the input. Each test case starts with
a line containg two integers x, y such that 1 <= x,y <= 50. After
this, y lines follow, each which x characters. For each character, a
space `` '' stands for an open space, a hash mark ``#'' stands for an
obstructing wall, the capital letter ``A'' stand for an alien, and the
capital letter ``S'' stands for the start of the search. The perimeter
of the maze is always closed, i.e., there is no way to get out from the
coordinate of the ``S''. At most 100 aliens are present in the maze, and
everyone is reachable.
Output
of a succesful search of the maze leaving no aliens alive.
Sample Input
- 2
- 6 5
- #####
- #A#A##
- # # A#
- #S ##
- #####
- 7 7
- #####
- #AAA###
- # A#
- # S ###
- # #
- #AAA###
- #####
Sample Output
- 8
- 11
- 思路:对每个S或A进行编号,bfs求各点之间互相到达的最短距离建图,然后kruskal
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <queue>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt,xx,yy;
- char maze[][];
- int a[][];
- int dr[] = {, , -, };
- int dc[] = {, , , -};
- int num;
- bool vis[][];
- struct node {
- int u, v, w;
- }e[maxn];
- struct Node {
- int x, y;
- int step;
- };
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal()
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- if(++cnt == n-) {
- //break;
- }
- }
- }
- void bfs(int x, int y, int ans)
- {
- memset(vis,,sizeof(vis));
- queue <Node> q;
- Node temp;
- temp.x = x, temp.y = y, temp.step = ;
- vis[x][y] = ;
- q.push(temp);
- while(!q.empty()) {
- temp = q.front();
- q.pop();
- for(int i = ; i < ; i++) {
- Node nxt;
- nxt.x = temp.x + dr[i];
- nxt.y = temp.y + dc[i];
- nxt.step = temp.step + ;
- //printf("a[%d][%d]:%d vis[%d][%d]:%d\n",nxt.x,nxt.y,a[nxt.x][nxt.y],nxt.x,nxt.y,vis[nxt.x][nxt.y]);
- if(nxt.x >= && nxt.y >= && nxt.x <= xx && nxt.y <= yy &&
- !vis[nxt.x][nxt.y] && a[nxt.x][nxt.y] != -) {
- vis[nxt.x][nxt.y] = ;
- q.push(nxt);
- //printf("a[%d][%d] : %d\n",nxt.x,nxt.y,a[nxt.x][nxt.y]);
- if(a[nxt.x][nxt.y] > ) {
- e[m].u = ans, e[m].v = a[nxt.x][nxt.y];
- e[m++].w = nxt.step;
- //printf("u:%d v:%d w:%d\n",e[m-1].u,e[m-1].v,e[m-1].w);
- //printf("num!:%d\n",m);
- }
- }
- }
- }
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--) {
- scanf("%d %d",&yy, &xx);
- getchar();
- n = , m = ;
- memset(a,,sizeof(a));
- for(int i = ; i <= xx; i++) {
- char ch[];
- gets(ch);
- for(int j = ; j < yy; j++) {
- if(ch[j] == '#') a[i][j+] = -;
- else if(ch[j] == 'A' || ch[j] == 'S') a[i][j+] = n++;
- else if(ch[j] == ' ') a[i][j+] = ;
- //printf("a[%d][%d]:%d\n",i,j+1,a[i][j+1]);
- }
- }
- //printf("\n");
- for(int i = ; i <= xx; i++) {
- for(int j = ; j <= yy; j++) {
- if(a[i][j] > ) {
- bfs(i,j,a[i][j]);
- //printf("num:%d\n",m);
- }
- }
- }
- //printf("n:%d m:%d\n",n,m);
- n--;
- m--;
- init(n);
- kruskal();
- printf("%d\n",ans);
- }
- return ;
- }
J - The Unique MST
Definition 1 (Spanning Tree): Consider a connected,
undirected graph G = (V, E). A spanning tree of G is a subgraph of G,
say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an
edge-weighted, connected, undirected graph G = (V, E). The minimum
spanning tree T = (V, E') of G is the spanning tree that has the
smallest total cost. The total cost of T means the sum of the weights on
all the edges in E'.
Input
the number of test cases. Each case represents a graph. It begins with a
line containing two integers n and m (1 <= n <= 100), the number
of nodes and edges. Each of the following m lines contains a triple (xi,
yi, wi), indicating that xi and yi are connected by an edge with weight
= wi. For any two nodes, there is at most one edge connecting them.
Output
Sample Input
- 2
- 3 3
- 1 2 1
- 2 3 2
- 3 1 3
- 4 4
- 1 2 2
- 2 3 2
- 3 4 2
- 4 1 2
Sample Output
- 3
- Not Unique!
思路:对于唯一生成树问题,我们可以通过对重边的标记,在进行kruskal时跳过用过的重边,判断是否能够找到边权相同的最小生成树。也有另外一种通过求次小生成树来判断MST是否唯一的方法,后续会补上。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt,ok,flag;
- struct node{
- int u, v, w;
- int used,del,rep;//使用过,删掉惹,重复边
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- e[i].del = , e[i].rep = , e[i].used = ;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- int kruskal(int m)
- {
- ans = ;
- for(int i = ; i <= m; i++) {
- //printf("!\n");
- if(e[i].del) continue;
- //printf("?\n");
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- //printf("eu:%d ev:%d\n",eu,ev);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- //cout << "e[i].w:" << e[i].w << endl;
- if(!flag) e[i].used = ;
- fa[ev] = eu;
- //printf("ok:%d e[i].w:%d e[i-1].w:%d\n",ok,e[i].w,e[i-1].w);
- if(++cnt == n-) {
- break;
- }
- }
- //printf("ans:%d\n",ans);
- return ans;
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--) {
- ok = ;
- scanf("%d %d",&n,&m);
- for(int i = ; i <=m; i++) {
- scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
- }
- init(n);
- for(int i = ; i <= m; i++) {
- for(int j = ; j <= m; j++) {
- if(j == i) continue;
- if(e[i].w == e[j].w) {
- e[i].rep = ;
- //printf("e[%d]:%d\n",i,e[i].rep);
- }
- }
- }
- flag = ;
- sort(e+, e+m+, cmp);
- int res = kruskal(m);
- flag = ;
- for(int i = ; i <= n; i++) {
- //printf("e[%d]:%d\n",i,e[i].rep);
- if(e[i].rep == && e[i].used == ) {
- //init(n);
- e[i].del = ;
- int temp;
- for(int g = ; g <= n ; g++) {
- fa[g] = g;
- }
- temp = kruskal(m);
- e[i].del = ;
- //printf("temp:%d\n",temp);
- if(temp == res) {
- printf("Not Unique!\n");
- ok = ;
- break;
- }
- }
- }
- if(!ok) {
- printf("%d\n",res);
- }
- }
- return ;
- }
K - 还是畅通工程
当N为0时,输入结束,该用例不被处理。
Output对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
- 3
- 1 2 1
- 1 3 2
- 2 3 4
- 4
- 1 2 1
- 1 3 4
- 1 4 1
- 2 3 3
- 2 4 2
- 3 4 5
- 0
Sample Output
- 3
- 5
- Huge input, scanf is recommended.
Hint
- Hint
- 思路:建图+kruskal
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,ans,eu,ev,cnt;
- struct node{
- int u, v, w;
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = ;
- cnt = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- if(++cnt == n-) {
- break;
- }
- }
- }
- int main()
- {
- m = ;
- while(scanf("%d",&n) && n) {
- int m = n * (n-) / ;
- for(int i = ; i <= m; i++) {
- scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
- }
- init(n);
- kruskal(m);
- printf("%d\n",ans);
- }
- return ;
- }
L - Jungle Roads
The Head Elder of the tropical island of Lagrishan has a problem. A
burst of foreign aid money was spent on extra roads between villages
some years ago. But the jungle overtakes roads relentlessly, so the
large road network is too expensive to maintain. The Council of Elders
must choose to stop maintaining some roads. The map above on the left
shows all the roads in use now and the cost in aacms per month to
maintain them. Of course there needs to be some way to get between all
the villages on maintained roads, even if the route is not as short as
before. The Chief Elder would like to tell the Council of Elders what
would be the smallest amount they could spend in aacms per month to
maintain roads that would connect all the villages. The villages are
labeled A through I in the maps above. The map on the right shows the
roads that could be maintained most cheaply, for 216 aacms per month.
Your task is to write a program that will solve such problems.
The input consists of one to 100 data sets, followed by a final
line containing only 0. Each data set starts with a line containing only
a number n, which is the number of villages, 1 < n < 27, and the
villages are labeled with the first n letters of the alphabet,
capitalized. Each data set is completed with n-1 lines that start with
village labels in alphabetical order. There is no line for the last
village. Each line for a village starts with the village label followed
by a number, k, of roads from this village to villages with labels later
in the alphabet. If k is greater than 0, the line continues with data
for each of the k roads. The data for each road is the village label for
the other end of the road followed by the monthly maintenance cost in
aacms for the road. Maintenance costs will be positive integers less
than 100. All data fields in the row are separated by single blanks. The
road network will always allow travel between all the villages. The
network will never have more than 75 roads. No village will have more
than 15 roads going to other villages (before or after in the alphabet).
In the sample input below, the first data set goes with the map above.
The output is one integer per line for each data set: the minimum
cost in aacms per month to maintain a road system that connect all the
villages. Caution: A brute force solution that examines every possible
set of roads will not finish within the one minute time limit.
- 9
- A 2 B 12 I 25
- B 3 C 10 H 40 I 8
- C 2 D 18 G 55
- D 1 E 44
- E 2 F 60 G 38
- F 0
- G 1 H 35
- H 1 I 35
- 3
- A 2 B 10 C 40
- B 1 C 20
- 0
Output
- 216
- 30
Sample Input
- 9
- A 2 B 12 I 25
- B 3 C 10 H 40 I 8
- C 2 D 18 G 55
- D 1 E 44
- E 2 F 60 G 38
- F 0
- G 1 H 35
- H 1 I 35
- 3
- A 2 B 10 C 40
- B 1 C 20
- 0
Sample Output
- 216
- 30
- 思路:别问,问就是bin巨的锅
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int maxn = ;
- int fa[],n,m,ans,eu,ev,cnt,t;
- struct node{
- int u, v, w;
- }e[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void kruskal()
- {
- sort(e, e+m, cmp);
- for(int i = ; i < m; i++) {
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- ans += e[i].w;
- fa[ev] = eu;
- /*if(++cnt == n-1) {
- break;
- }*/
- }
- }
- int main()
- {
- while(scanf("%d",&n)) {
- if(!n) break;
- for(int i = ; i <= ; i++) {
- fa[i] = i;
- }
- int t = n-;
- m = ;
- ans = ;
- while(t--) {
- char ch;
- int num;
- cin >> ch >> num;
- while(num--) {
- char vge;
- int cost;
- cin >> vge >> cost;
- e[m].u = ch-;
- e[m].v = vge-;
- e[m].w = cost;
- m++;
- }
- }
- /*for(int i = 0; i < m; i++) {
- printf("e[%d].u:%d e[%d].v:%d e[%d].w:%d\n",i,e[i].u,i,e[i].v,i,e[i].w);
- }*/
- kruskal();
- printf("%d\n",ans);
- }
- return ;
- }
M - 畅通工程再续
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
Output每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.Sample Input
- 2
- 2
- 10 10
- 20 20
- 3
- 1 1
- 2 2
- 1000 1000
Sample Output
- 1414.2
- 思路:建图后kruskal,注意一些细节,比如double和对t比到1e(-6)级,另外一些题意上的坑点详见hdu里此题讨论区
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <cmath>
- using namespace std;
- const int maxn = 2e5+;
- ///把所有边排序,记第i小的边为:e[i](1 <= i < m)
- ///初始化MST为空
- ///初始化连通分量,让每个点自成一个独立的连通分量
- ///for(int i = 0; i < m; i++) {
- /// if(e[i].u 和 e[i].v 不在同一个连通分量) {
- /// 把边e[i]加入MST
- /// 合并e[i].u 和 e[i].v 所在的连通分量
- /// }
- ///}
- int fa[],n,m,eu,ev,cnt,ok;
- double ans;
- struct node{
- int u, v;
- double w;
- }e[maxn];
- struct Node {
- int x,y;
- }a[maxn];
- bool cmp(node a, node b)
- {
- return a.w < b.w;
- }
- int fid(int x)
- {
- return x == fa[x] ? x : fid(fa[x]);
- }
- void init(int n)
- {
- for(int i = ; i <= n; i++) {
- fa[i] = i;
- }
- ans = 0.0;
- cnt = ;
- ok = ;
- }
- bool unite(int r1, int r2)///冰茶鸡
- {
- int fidroot1 = fid(r1), fidroot2 = fid(r2);
- if(fidroot1 != fidroot2) {
- fa[fidroot2] = fidroot1;
- return true;
- }
- return false;
- }
- void kruskal(int m)
- {
- sort(e+, e+m+, cmp);
- for(int i = ; i <= m; i++) {
- //printf("e[%d]:%f\n",i,e[i].w);
- eu = fid(e[i].u);
- ev = fid(e[i].v);
- if(eu == ev) {
- continue;
- }
- if(e[i].w >= 10.000000 && e[i].w <= 1000.0000001) {
- ans += e[i].w;
- fa[ev] = eu;
- //printf("ans:%.1f cnt:%d\n",ans,cnt);
- if(++cnt == n-) {
- ok = ;
- break;
- }
- }
- }
- if(ok) {
- printf("%.1f\n",ans * );
- }
- else {
- printf("oh!\n");
- }
- }
- double dist(Node a, Node b)
- {
- return sqrt((a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y));
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--) {
- scanf("%d",&n);
- for(int i = ; i <= n; i++) {
- scanf("%d %d",&a[i].x,&a[i].y);
- }
- m = ;
- for(int i = ; i <= n; i++) {
- for(int j = ; j <= n; j++) {
- if(i == j) {
- continue;
- }
- else {
- e[m].u = i, e[m].v = j;
- e[m++].w = dist(a[i],a[j]);
- }
- }
- }
- m--;
- init(n);
- kruskal(m);
- }
- return ;
- }
【kuangbin带你飞】 MST专题的更多相关文章
- 「kuangbin带你飞」专题十四 数论基础
layout: post title: 「kuangbin带你飞」专题十四 数论基础 author: "luowentaoaa" catalog: true tags: mathj ...
- 「kuangbin带你飞」专题二十 斜率DP
layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathj ...
- 「kuangbin带你飞」专题二十二 区间DP
layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...
- 「kuangbin带你飞」专题十九 矩阵
layout: post title: 「kuangbin带你飞」专题十九 矩阵 author: "luowentaoaa" catalog: true tags: mathjax ...
- 「kuangbin带你飞」专题十八 后缀数组
layout: post title: 「kuangbin带你飞」专题十八 后缀数组 author: "luowentaoaa" catalog: true tags: - kua ...
- 「kuangbin带你飞」专题十七 AC自动机
layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...
- 「kuangbin带你飞」专题十二 基础DP
layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...
- kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数
第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...
- kuangbin带你飞dp专题-基础dp
dp HDU - 1257 最少拦截系统 最长递增子序列 #include<iostream> using namespace std; const int maxn=1e7; int a ...
- 「kuangbin带你飞」专题十五 数位DP
传送门 A.CodeForces - 55D Beautiful numbers 题意 一个正整数是 漂亮数 ,当且仅当它能够被自身的各非零数字整除.我们不必与之争辩,只需计算给定范围中有多少个漂亮数 ...
随机推荐
- .NET CORE(C#) WPF简单菜单MVVM绑定
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF简单菜单MVVM绑定 阅读导航 本文背景 代码实现 本文参考 ...
- Spring Boot 2从入门到放弃(持续更新)
入门 Spring Boot 2项目的搭建和启动(入门篇1) Spring Boot 2项目的搭建和启动(入门篇2) spring boot 2项目自定义父pom Spring Boot 2开发工具s ...
- HTTPS原理及流程
HTTPS为什么更安全:数据对称加密传出,对称密钥使用非对称加密协商. HTTPS就一定安全吗:不一定,如果用户在浏览器端执意访问证书可疑或过期的站点,就存在安全隐患. --- HTTPS实现原理:h ...
- Sap Hana 关于BP的一些理解
BP里面有角色和角色分组,角色分组相当于包含多个角色. 客户和供应商使用不同的角色来创建. 创建角色和分组前可以创建自定义的角色类别和角色分组类别. 文档:关于BP.note 链接:笔记 作者:明光烁 ...
- oo第三次作业--jml
1.首先我们应该了解什么是jml,jml是java modeling language的缩写,是一种为java规格化设计的标识语言,简单来说,就是描述“干什么”的标准语言(跟注释差不多,但是是标准化注 ...
- 深度(deepin)系统不能ssh root用户登录
vi /etc/ssh/sshd_config找到这一部分信息刚进去信息应该是这样 # Authentication: #LoginGraceTime 2m #PermitRootLogin proh ...
- 定义了一个vue全局方法,不能再vuex中进行调用
你把函数定义在 Vue 的原型链上,只能在 Vue 的实例里才能取到这个方法. vue组件 是一个Vue 的实例,所以你当然能在这里调用到 ajax 方法. 而,vuex 只是一个 vue插件,在 v ...
- Oracle v$session视图显示客户端IP地址
在Oracle数据库中,我们使用session相关视图(v$session.v$active_session_history,dba_hist_active_session_history等)查找问题 ...
- python中的“赋值与深浅拷贝”
Python中,赋值与拷贝(深/浅拷贝)之间是有差异的,这主要源于数据在内存中的存放问题,本文将对此加以探讨. 1 赋值(添加名字) 赋值不会改变内存中数据存放状态,比如在内存中存在一个名为data的 ...
- Map的底层实现原理
一,前言 1.1,概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射(K-V).Java提供了专门的集合类用 ...