Los P1265 Valley highway construction solution to a problem

Title Description

A state-owned n cities, roads connecting them to each other is not between, so the traffic is very inconvenient. To solve the "hard road" of the problem, the government decided to build the road. Road construction by the city together to complete the task.

The construction works were divided into several rounds completed. In each round, each city to select a city and its recent application to build roads leading to the city. Government is responsible for approving these applications to decide whether to agree to build.

Government approval rules are as follows:

(1) If two or more cities to apply to build the same road, then let them build together;

Highway (2) If three or more applications built city ring. Below, A road construction applications AB, B road construction applications BC, C apply for the construction of roads CA. The government will reject the application in which the shortest construction of a road;

(3) apply for all other cases of consent.

After a construction, there may be a number of cities may be directly or indirectly connected by road. These can be each other: namely communicated city formed a "Coalition of Cities." In the next round of construction, each of the "Cities Alliance" will be seen as a city, to play the role of a city.

When all cities are combined into a "Cities Alliance", the construction project is complete.

Your task is distributed according to the rules and in front of the city mentioned, calculate the total length of the highway will be built.

Input Format

The first line an integer n, the number of cities. (N≤5000)

The following n lines of two integers x and y, coordinates representing a city. (-1000000≤x, y≤1000000)

Output Format

A real number, rounded to two decimal places, express road length. (Ensure that there is a unique solution)

Sample input and output

Input # 1
4
0 0
1 2
-1 2
0 4
Output # 1
6.47

Description / Tips

Road construction as shown:

 

Resolution:

MST bare title (do not accept beaten)

FIG because it is dense, so using Prim's algorithm
(preferably using Kruskal FIG sparse)
any two points are determined distance
and the minimum spanning tree of its run again
it is noted that n in the range 5000, the size is limited to 125MB

The subject itself is not difficult, but it would have been MLE, so it is necessary to optimize

I've got three codes, different scores

The first is a bare open 5000 * 5000 Prim algorithm double array can be run out of 80 points, good results (not open O2). ,

The second is bare of Kruskal algorithm, do not open the O2 estimated 70 points, opened the O2 steady 80 points, 90 points is good luck

The third is Prim, Prim and the first difference is that will reduce the number of redundant operations, a concrete manifestation of the array is to cancel the 5000 * 5000

You will only need to calculate when calculated, will greatly reduce the time and memory ,,, so on the AC.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<string>
 6 #include<algorithm>
 7 #include<iomanip>
 8 #include<cstdlib>
 9 #include<queue>
10 #include<set>
11 #include<map>
12 #include<stack>
13 #include<vector>
14 #define LL long long
15 #define re register
16 #define INF 0x7fffffff
17 #define Max 5002
18 #define D double
19 inline int read()
20 {
21     int s=0,f=-1;char ch=getchar();
22     while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
23     while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
24     return s*f;
25 }
26 int n;D ans=0.0,g[Max][Max],dis[Max];
27 bool vis[Max]={0};
28 struct edge {
29     D x,y;
30 }t[Max];
31 D Dis(D x1,D y1,D x2,D y2)
32 {
33     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
34 }
35 int main()
36 {
37     scanf("%d",&n);
38     for(re int i = 1 ; i <= n ; ++ i) g[i][i]=0,scanf("%lf%lf",&t[i].x,&t[i].y);
39     for(re int i = 1 ; i <= n ; ++ i)
40         for(re int j = i+1 ; j <= n ; ++ j)
41             g[i][j]=g[j][i]=Dis(t[i].x,t[i].y,t[j].x,t[j].y);
42     int pos;vis[1]=1;
43     for(re int i = 1 ; i <= n ; ++ i) dis[i]=g[1][i];
44     for(re int i = 1 ; i < n ; ++ i) {
45         pos=0;
46         for(re int j = 1 ; j <= n ; ++ j) {
47             if(vis[j]==1) continue;
48             if(!pos || dis[j] < dis[pos]) pos=j;
49         }
50         vis[pos]=1;
51         ans+=dis[pos];
52         for(re int j = 1 ; j <= n ; ++ j) {
53             if(vis[j]==1) continue;
54             dis[j]=std::min(dis[j],g[pos][j]);
55         }
56     }
57     printf("%.2lf",ans);
58     return 0;
59 }
80 nude Prim
 1 // luogu-judger-enable-o2
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<string>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<cstdlib>
10 #include<queue>
11 #include<set>
12 #include<map>
13 #include<stack>
14 #include<vector>
15 #define LL long long
16 #define re register
17 #define Max 5000*5000/2
18 #define D double
19 inline int read()
20 {
21     int s=0,f=-1;char ch=getchar();
22     while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
23     while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
24     return s*f;
25 }
26 int n,pa[Max];D ans=0;
27 struct edge {
28     D x,y;
29 }t[Max];
30 struct DIS {
31     D dis;
32     int from,to;
33     friend bool operator<(DIS a,DIS b) {
34         return a.dis<b.dis;
35     }
36 }e[Max];
37 int find(int x)
38 {
39     if(x!=pa[x]) pa[x]=find(pa[x]);
40     return pa[x];
41 }
42 void join(int x,int y)
43 {
44     x=find(x);y=find(y);
45     pa[y]=x;
46 }
47 D Dis(D x1,D y1,D x2,D y2)
48 {
49     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
50 }
51 int main()
52 {
53     scanf("%d",&n);int cnt=0;
54     for(re int i = 1 ; i <= n ; ++ i) pa[i]=i,scanf("%lf%lf",&t[i].x,&t[i].y);
55     for(re int i = 1 ; i <= n ; ++ i)
56         for(re int j = i+1 ; j <= n ; ++ j)
57             e[++cnt].dis=Dis(t[i].x,t[i].y,t[j].x,t[j].y),e[cnt].from=i,e[cnt].to=j;
58     int k=0;
59     std::sort(e+1,e+1+cnt);
60     for(re int i = 1 ; i <= cnt ; ++ i) {
61         int x=e[i].from,y=e[i].to;D t=e[i].dis;
62         if(find(x)!=find(y)) join(x,y),ans+=t;
63         if(k==n-1) break;
64     }
65     printf("%.2lf",ans);
66      return  0 ;
67 }
Open O2 perhaps 90 minutes perhaps 80 minutes to see if your face black
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<string>
 6 #include<algorithm>
 7 #include<iomanip>
 8 #include<cstdlib>
 9 #include<queue>
10 #include<set>
11 #include<map>
12 #include<stack>
13 #include<vector>
14 #define LL long long
15 #define re register
16 #define INF 0x7fffffff
17 #define Max 5002
18 #define D double
19 inline int read()
20 {
21     int s=0,f=-1;char ch=getchar();
22     while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
23     while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
24     return s*f;
25 }
26 int n;D ans=0.0,dis[Max];
27 bool vis[Max]={0};
28 struct edge {D x,y;}t[Max];
29 D Dis(D x1,D y1,D x2,D y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
30 int main()
31 {
32     scanf("%d",&n);
33     for(re int i = 1 ; i <= n ; ++ i) dis[i]=INF,scanf("%lf%lf",&t[i].x,&t[i].y);
34     int pos;dis[1]=0;
35     for(re int i = 1 ; i <= n ; ++ i) {
36         D m=INF*1.0;
37         for(re int j = 1 ; j <= n ; ++ j)
38             if(dis[j] < m && !vis[j]) m=dis[j],pos=j;
39         vis[pos]=1;
40         ans+=m;
41         for(re int j = 1 ; j <= n ; ++ j) {
42             if(vis[j]==1) continue;
43             D d=Dis(t[pos].x,t[pos].y,t[j].x,t[j].y);
44             dis[j]=std::min(dis[j],d);
45         }
46     }
47     printf("%.2lf",ans);
48     return 0;
49 }
AC 代码

Guess you like

Origin www.cnblogs.com/handsomegodzilla/p/11291039.html