公路修建
http://218.5.5.242:9018/JudgeOnline/problem.php?id=1443
题目描述
某国有n个城市,它们互相之间没有公路相通,因此交通十分不便。为解决这一“行路难”的问题,政府决定修建公路。修建公路的任务由各城市共同完成。
修建工程分若干轮完成。在每一轮中,每个城市选择一个与它最近的城市,申请修建通往该城市的公路。政府负责审批这些申请以决定是否同意修建。
政府审批的规则如下:
(1)如果两个或以上城市申请修建同一条公路,则让它们共同修建;
(2)如果三个或以上的城市申请修建的公路成环。如下图,A申请修建公路AB,B申请修建公路BC,C申请修建公路CA。则政府将否决其中最短的一条公路的修建申请;
(3)其他情况的申请一律同意。
一轮修建结束后,可能会有若干城市可以通过公路直接或间接相连。这些可以互相:连通的城市即组成“城市联盟”。在下一轮修建中,每个“城市联盟”将被看作一个城市,发挥一个城市的作用。
当所有城市被组合成一个“城市联盟”时,修建工程也就完成了。
你的任务是根据城市的分布和前面讲到的规则,计算出将要修建的公路总长度。
输入
第一行一个整数n,表示城市的数量。(n≤5000)
以下n行,每行两个整数x和y,表示一个城市的坐标。(-1000000≤x,y≤1000000)
输出
一个实数,四舍五入保留两位小数,表示公路总长。
样例输入
1 2 3 4 5 6 |
<span class="sampledata">4 0 0 1 2 -1 2 0 4 </span> |
样例输出
1 |
<span class="sampledata">6.47</span> |
题解
竟然这么多边T T,然后我发现我从来没写过prim
就yy了一下
其实应该用灵界(雾)矩阵存的,但是我比较逗T T
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #define ll long long #define inf 1000000000 #define pa pair<double,int> using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,cnt; ll x[5005],y[5005]; int last[5005]; double ans,mn[5005]; bool vis[5005]; struct edge{int to,next;}e[25000005]; void ins(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; } void insert(int u,int v) { ins(u,v);ins(v,u); } inline double dis(int a,int b) { return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } void prim() { priority_queue<pa,vector<pa>,greater<pa> > q; for(int i=1;i<=n;i++)mn[i]=inf; mn[1]=0;q.push(make_pair(0,1)); while(!q.empty()) { int now=q.top().second;q.pop(); if(vis[now])continue;vis[now]=1; ans+=mn[now]; for(int i=last[now];i;i=e[i].next) { int to=e[i].to;double v=dis(now,to); if(v<mn[to]) { mn[to]=v; q.push(make_pair(mn[to],to)); } } } } int main() { n=read(); for(int i=1;i<=n;i++) { x[i]=read();y[i]=read(); } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) insert(i,j); prim(); printf("%.2lf",ans); return 0; } |