1 条题解

  • 0
    @ 2026-6-15 11:36:21

    // 最小生成树 Prim算法 O(n^2)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=7505,M=2019201997;
    int n,k,cnt;
    vector<pair<int,int>> e[N];
    int d[N],vis[N],q[N];
    
    void prim(){
      for(int i=0;i<=n;i++) d[i]=M; d[1]=0;
      for(int i=1,u;i<=n;i++){
        u=0;
        for(int j=1;j<=n;j++)if(!vis[j]&&d[j]<d[u]) u=j;
        vis[u]=1;
        if(d[u]) q[++cnt]=d[u]; //记录边权
        for(auto [v,w]:e[u])if(d[v]>w) d[v]=w;
      }
      
      sort(q+1,q+cnt+1);
      printf("%d\n",q[n-k+1]);
    }
    int main(){
      cin>>n>>k;
      for(int i=1,w;i<n;i++)for(int j=i+1;j<=n;j++){
        w=(1ll*2019201913*i%M+1ll*2019201949*j%M)%M;
        e[i].push_back({j,w});
        e[j].push_back({i,w});
      }
      
      prim();
    }
    
    // 最小生成树 Kruskal算法 O(MlogM) TLE两点
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=7505,M=N*N/2,P=2019201997;
    int n,k,m,tot,ans,fa[N];
    pair<int,pair<int,int> >e[M]; //边集
    
    int find(int u){ //并查集的找根
      return fa[u]==u?u:fa[u]=find(fa[u]);
    }
    void kruskal(){
      sort(e+1,e+m+1); //排序
      for(int i=1; i<=n; i++) fa[i]=i;
      for(int i=1; i<=m; 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-k+1) break;
        }
      }
      cout<<ans;
    }
    signed main(){
      cin>>n>>k;
      for(int i=1;i<n;i++)for(int j=i+1;j<=n;j++){
        e[++m]={(1ll*2019201913*i%P+1ll*2019201949*j%P)%P,{i,j}};
      }
        
      kruskal();
    }
    
    • 1

    D135 最小生成树 Prim 算法[USACO19OPEN] I Would Walk 500 Miles G

    信息

    ID
    6946
    时间
    2000ms
    内存
    512MiB
    难度
    8
    标签
    递交数
    74
    已通过
    12
    上传者