【最小生成树】洛谷 P2872 Building Roads S
2021-06-04 20:44:00
# ACM
题链
先求出每两个点的距离,再根据已有的边,将其赋值为$0$,然后跑一遍最小生成树;
$Kruskal$
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #include <bits/stdc++.h> using namespace std; #define ls rt<<1 #define rs rt<<1|1 #define LL long long #define PI acos(-1.0) #define eps 1e-8 #define Pair pair<double,double>
#define mod 998244353 #define MAXN 2e6 #define MS 1009
LL n,m; struct node{ double x,y; }p[MS]; double dis[MS][MS]; struct nod{ int u,v; double w; }e[MS*MS]; int fa[MS]; int tot;
bool cmp(nod t1,nod t2){ return t1.w < t2.w; }
double sqr(double x){ return x*x; }
double qdis(node t1,node t2){ return sqrt( sqr(t1.x-t2.x) + sqr(t1.y-t2.y) ); }
int find(int x){ if(x == fa[x]) return x; return fa[x] = find(fa[x]); }
void merge(int x,int y){ fa[find(y)] = find(x); }
int main() { cin >> n >> m; for(int i=1;i<=n;i++){ double x,y; cin >> x >> y; p[i] = {x,y}; fa[i] = i; } for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ dis[i][j] = qdis(p[i],p[j]); } } while(m--){ int u,v; cin >> u >> v; if(u > v) swap(u,v); dis[u][v] = 0; } for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ e[++tot] = {i,j,dis[i][j]}; } } sort(e+1,e+tot+1,cmp); int cc = 0; double ans = 0; for(int i=1;i<=tot && cc < n-1;i++){ nod t = e[i]; if(find(t.u) != find(t.v)){ ans += t.w; merge(t.u,t.v); cc++; } } printf("%.2f\n",ans);
return 0; }
|
$Prim$
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <bits/stdc++.h> using namespace std; #define ls rt<<1 #define rs rt<<1|1 #define LL long long #define PI acos(-1.0) #define eps 1e-8 #define Pair pair<double,double>
#define mod 998244353 #define MAXN 1e18 #define MS 1009
LL n,m; struct node{ double x,y; }a[MS]; double p[MS][MS]; int v[MS]; double dis[MS]; struct nod{ int poi; double val; }; priority_queue<nod > Q;
bool operator < (nod t1,nod t2){ return t1.val > t2.val; }
double sqr(double x){ return x*x; }
double qdis(node t1,node t2){ return sqrt( sqr(t1.x-t2.x) + sqr(t1.y-t2.y) ); }
double bfs(int x){ for(int i=1;i<=n;i++){ dis[i] = MAXN; } dis[x] = 0; Q.push({x,0}); double ans = 0; while(!Q.empty()){ nod t = Q.top(); Q.pop(); if(v[t.poi]) continue; v[t.poi] = 1; ans += t.val; for(int i=1;i<=n;i++){ if(dis[i] > p[t.poi][i]){ dis[i] = p[t.poi][i]; if(!v[i]){ Q.push({i,p[t.poi][i]}); } } } } return ans; }
int main() { cin >> n >> m; for(int i=1;i<=n;i++){ double x,y; cin >> x >> y; a[i] = {x,y}; } for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ p[j][i] = p[i][j] = qdis(a[i],a[j]); } } while(m--){ int u,v; cin >> u >> v; p[v][u] = p[u][v] = 0; } double ans = bfs(1); printf("%.2f",ans);
return 0; }
|
2021-06-04 20:44:00
# ACM