3 条题解

  • 0
    @ 2026-6-15 11:47:41

    // 最小生成树 Kruskal算法 O(MlogM)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1010,M=1000010;
    int n,m,tot,cnt,x[N],y[N],fa[N];
    double ans;
    pair<double,pair<int,int> >e[M]; //边集
    
    int find(int u){ //并查集的找根
      return fa[u]==u?u:fa[u]=find(fa[u]);
    }
    void kruskal(){
      for(int i=1;i<=n;i++) fa[i]=i;
      sort(e+1,e+cnt+1); //排序
      for(int i=1; i<=cnt; i++){
        int x=find(e[i].second.first),y=find(e[i].second.second);
        if(x!=y){
          fa[x]=y;
          ans+=e[i].first;
          if(++tot==n-1) break;
        }
      }
      printf("%.2lf\n",ans);
    }
    int main(){
      cin>>n>>m;
      for(int i=1;i<=n;i++){
        scanf("%d %d",&x[i],&y[i]);
        for(int j=1;j<i;j++){
          double d=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j]));
          e[++cnt]={d,{i,j}};
        }
      }
      for(int i=1,u,v; i<=m; i++){
        scanf("%d %d",&u,&v);
        e[++cnt]={0.0,{u,v}}; //m条边必选
      }
        
      kruskal();
    }
    
    • 0
      @ 2025-10-8 16:56:54
      #include<bits/stdc++.h>
      using namespace std;
      const int N=1010;
      #define PII pair<double,double>
      #define fi first
      #define se second
      PII a[N];
      double dis(PII n1,PII n2){return sqrt((n1.fi-n2.fi)*(n1.fi-n2.fi)+(n1.se-n2.se)*(n1.se-n2.se));}
      struct node{int x,y;double c;}e[N*N];
      bool cmp(node n1,node n2){return n1.c<n2.c;}
      int fa[N];
      int findfa(int x){return fa[x]==x?fa[x]:fa[x]=findfa(fa[x]);}
      int main()
      {
          int n,m;cin>>n>>m;
          for(int i=1;i<=n;i++)cin>>a[i].fi>>a[i].se;
          int len=0;
          for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)e[++len]={i,j,dis(a[i],a[j])};
          for(int i=1;i<=n;i++)fa[i]=i;
          for(int i=1;i<=m;i++)
          {
              int x,y;cin>>x>>y;
              int tx=findfa(x),ty=findfa(y);
              fa[tx]=ty;
          }
          sort(e+1,e+len+1,cmp);
          int sum=m;double ans=0;
          for(int i=1;i<=len;i++)
          {
              int tx=findfa(e[i].x),ty=findfa(e[i].y);
              if(tx!=ty)
              {
                  fa[tx]=ty;
                  sum++;ans+=e[i].c;
                  if(sum==n-1)break;
              }
          }
          printf("%.2lf",ans);
          return 0;
      }
      
      • 0
        @ 2025-10-8 16:56:46

        qkw代码:

        #include<bits/stdc++.h>
        using namespace std;
        const int N=1010;
        #define PII pair<double,double>
        #define fi first
        #define se second
        PII a[N];
        double dis(PII n1,PII n2){return sqrt((n1.fi-n2.fi)*(n1.fi-n2.fi)+(n1.se-n2.se)*(n1.se-n2.se));}
        struct node{int x,y;double c;}e[N*N];
        bool cmp(node n1,node n2){return n1.c<n2.c;}
        int fa[N];
        int findfa(int x){return fa[x]==x?fa[x]:fa[x]=findfa(fa[x]);}
        int main()
        {
            int n,m;cin>>n>>m;
            for(int i=1;i<=n;i++)cin>>a[i].fi>>a[i].se;
            int len=0;
            for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)e[++len]={i,j,dis(a[i],a[j])};
            for(int i=1;i<=n;i++)fa[i]=i;
            for(int i=1;i<=m;i++)
            {
                int x,y;cin>>x>>y;
                int tx=findfa(x),ty=findfa(y);
                fa[tx]=ty;
            }
            sort(e+1,e+len+1,cmp);
            int sum=m;double ans=0;
            for(int i=1;i<=len;i++)
            {
                int tx=findfa(e[i].x),ty=findfa(e[i].y);
                if(tx!=ty)
                {
                    fa[tx]=ty;
                    sum++;ans+=e[i].c;
                    if(sum==n-1)break;
                }
            }
            printf("%.2lf",ans);
            return 0;
        }
        • 1

        D131【最小生成树】[USACO07DEC] Building Roads S

        信息

        ID
        1411
        时间
        1000ms
        内存
        128MiB
        难度
        4
        标签
        递交数
        61
        已通过
        27
        上传者