jzoj1405-电缆建设【贪心,最小生成树】
生活随笔
收集整理的這篇文章主要介紹了
jzoj1405-电缆建设【贪心,最小生成树】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://jzoj.net/senior/#main/show/1405
題目大意
兩個平行于xxx軸的線上有若干個點,求連接所有點需要多少距離的線。
解題思路
在同一平行線上的相鄰的連邊,然后在不同的上面的話就離最近的兩個,跑最小生成樹即可。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<cmath> #define sqr(x) (1ll*(x)*(x)) using namespace std; const int N=601000*2; struct node{int x,y;long long w; }a[N*2]; int n,m,x1,x2,fa[N],y[N],tot; double ans; int read() {int x=0,f=1; char c=getchar();while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();return x*f; } bool cmp(node x,node y) {return x.w<y.w;} int find(int x) {return (fa[x]==x)?x:(fa[x]=find(fa[x]));} int main() {n=read();m=read();x1=read();x2=read();for(int i=1;i<=n;i++)fa[i]=i,y[i]=y[i-1]+read();for(int i=n+1;i<=n+m;i++)fa[i]=i,y[i]=y[i-1]*(i!=n+1)+read();for(int i=1;i<n;i++)a[++tot]=(node){i,i+1,sqr(y[i+1]-y[i])};for(int i=n+1;i<n+m;i++)a[++tot]=(node){i,i+1,sqr(y[i+1]-y[i])};int l=n+1;for(int i=1;i<=n;i++){while(l<n+m&&y[l]<y[i]) l++;a[++tot]=(node){i,l,1ll*sqr(y[i]-y[l])+1ll*sqr(x1-x2)};if(l>n+1) a[++tot]=(node){i,l-1,1ll*sqr(y[i]-y[l-1])+1ll*sqr(x1-x2)}; }sort(a+1,a+1+tot,cmp);int z=n+m-1;for(int i=1;i<=tot;i++){int Fa=find(a[i].x),Fb=find(a[i].y);if(Fa==Fb) continue;ans+=sqrt(1.0*a[i].w);z--;fa[Fa]=Fb;if(!z) break;}printf("%.2lf",ans); }總結
以上是生活随笔為你收集整理的jzoj1405-电缆建设【贪心,最小生成树】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在电脑上录制游戏怎么在电脑上录制游戏
- 下一篇: P4310-绝世好题【位运算,dp】