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
4 0 0 1 2 -1 2 0 4
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 }
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 }
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 }