BZOJ_1626_[Usaco2007_Dec]_Building_Roads_修建道路_(Kruskal)

描述



http://www.lydsy.com/JudgeOnline/problem.php?id=1626

给出\(n\)个点的坐标,其中一些点已经连通,现在要把所有点连通,求修路的最小长度.

分析



已经连好一些边的最小生成树问题.

这里顺带复习了一下Prim和Krusakal.

Prim的证明:

设当前已经连好的树为\(T\),当前最小的边为\(e\),我们来证明\(e\)一定在最小生成树\(G\)中.

假设\(e\)不在\(G\)中,则连通\(G-T\)和\(T\)的边\(e‘\)一定比\(e\)大(或相等).此时我们在\(G\)中加入\(e\),会形成环,去掉环中的\(e‘\),树依然连通,而花费更小了,这与\(G\)是最小生成树矛盾.(如果\(e\)与\(e‘\)相等那么虽然花费不会更小,也就是说\(e\)可以不再\(G\)中,但是我们也可以用\(e\)替换\(e‘\),换言之,\(e\)在\(G\)中是不错误的.)

所以\(e\)一定在最小生成树\(G\)中.

Kruskal的证明:

设当前连接两个不连通分量的最小的边为\(e\),我们来证明\(e\)一定在最小生成树\(G\)中.

假设\(e\)不再\(G\)中,则连通这两个分量的边\(e‘\)一定比\(e\)大(或相等).此时我们 在\(G\)中加入\(e\),会形成环,去掉环中的\(e‘\),树依然连通,而花费更小了,这与\(G\)是最小生成树矛盾.(如果\(e\)与 \(e‘\)相等那么虽然花费不会更小,也就是说\(e\)可以不再\(G\)中,但是我们也可以用\(e\)替换\(e‘\),换言之,\(e\)在 \(G\)中是不错误的.)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn=1000+5;
 5 struct pt{
 6     double x,y;
 7     pt(double x=0,double y=0):x(x),y(y){}
 8 }p[maxn];
 9 struct edge{
10     int from,to;
11     double d;
12     edge(){}
13     edge(int from,int to,double d):from(from),to(to),d(d){}
14     bool operator < (const edge &rhs) const { return d<rhs.d; }
15 }g[maxn*maxn];
16 int n,m,cnt=1;
17 int f[maxn];
18 double ans;
19 inline double dis(pt a,pt b){ return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)); }
20 inline int find(int x){ return x==f[x]?x:f[x]=find(f[x]); }
21 int main(){
22     scanf("%d%d",&n,&m);
23     for(int i=1;i<=n;i++){
24         scanf("%lf%lf",&p[i].x,&p[i].y);
25         f[i]=i;
26     }
27     for(int i=1;i<=m;i++){
28         int u,v; scanf("%d%d",&u,&v);
29         int fu=find(u),fv=find(v);
30         if(fu!=fv) f[fu]=fv,cnt++;
31     }
32     for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) g[(i-1)*n+j]=edge(i,j,dis(p[i],p[j]));
33     sort(g+1,g+1+n*n);
34     int tot=n*n;
35     for(int i=1;i<=tot,cnt<=n;i++){
36         int fx=find(g[i].from),fy=find(g[i].to);
37         if(fx!=fy){
38             f[fx]=fy;
39             ans+=dis(p[g[i].from],p[g[i].to]);
40             cnt++;
41         }
42     }
43     printf("%.2lf\n",ans);
44     return 0;
45 }

时间: 2024-10-24 14:52:58

BZOJ_1626_[Usaco2007_Dec]_Building_Roads_修建道路_(Kruskal)的相关文章

POJ 2421 Constructing Roads 修建道路 最小生成树 Kruskal算法

题目链接:POJ 2421 Constructing Roads 修建道路 Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19698   Accepted: 8221 Description There are N villages, which are numbered from 1 to N, and you should build some roads such that e

[BZOJ] 1626: [Usaco2007 Dec]Building Roads 修建道路

1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1724  Solved: 725[Submit][Status][Discuss] Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场).有些农场之间原本就有道路相连. 所

[BZOJ1626][Usaco2007 Dec]Building Roads 修建道路

1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1730  Solved: 727 [Submit][Status][Discuss] Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场).有些农场之间原本就有道路相连.

bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路 -- 最小生成树

1626: [Usaco2007 Dec]Building Roads 修建道路 Time Limit: 5 Sec  Memory Limit: 64 MB Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场).有些农场之间原本就有道路相连. 所有N(1 <= N <= 1,000)个农场(用1..N顺次编号)在地图上都表示为坐标为(X_i,

BZOJ 1626: [Usaco2007 Dec]Building Roads 修建道路( MST )

计算距离时平方爆了int结果就WA了一次...... ----------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<cmath

【图论】畅通道路 prim Kruskal

最近在整理图论的算法.并且做了一些基础的题来练习,现在做一个总结,然后准备进入下一类算法的复习. 算法这个东西,就是不要害怕去编,哪怕自己只是有一点点理解,有好多点的模糊, 找一道基础的题, 对应着有一种思路解答的,去学习代码,学习里面的思路,并且自己动手跟着敲一敲,慢慢的就会理解了.    不用想着一开始就能够很彻底的理解算法的细节上思想. 理解的时候,从它所要达到的目的去思考, 知道它是要做一个什么事情,这是第一步.后面慢慢的多去练,就会更加深刻的理解里面的思想了,包括细节部分, 也会一点一

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

[Usaco2007 Dec]Building Roads 修建道路[最小生成树]

Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场).有些农场之间原本就有道路相连. 所有N(1 <= N <= 1,000)个农场(用1..N顺次编号)在地图上都表示为坐标为(X_i, Y_i)的点(0 <= X_i <= 1,000,000:0 <= Y_i <= 1,000,000),两个农场间道路的长度自然就是代

bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路【最小生成树】

先把已有的边并查集了,然后MST即可 记得开double #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int N=1005; int n,m,f[N],con,tot; double x[N],y[N],ans; struct qwe { int u,v; double w; }e[N*N]; bool c