• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ACM s1124yy
守りたいものが 強くさせること
博客园    首页    新随笔    联系   管理     

Kruskal算法

Kruskal算法

紫书P356

这是最小生成树(也叫MST)的算法。
这里的这个排序cmp函数还是比较牛逼的,他是根据w的值排序得到w的下标递增值。
i.e.这个排序可以保留w数组不动,但又可以得到拍好序的下标值,存在r数组中。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
#define cle(a,val) memset(a,(val),sizeof(a))
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d %d",&(N),&(M))
#define SIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
#define rep(i,b) for(int i=0;i<(b);i++)
#define rez(i,a,b) for(int i=(a);i<=(b);i++)
#define red(i,a,b) for(int i=(a);i>=(b);i--)
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define PU(x) puts(#x);
#define PI(A) cout<<(A)<<endl;
#define DG(x) cout<<#x<<"="<<(x)<<endl;
#define DGG(x,y) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<endl;
#define DGGG(x,y,z) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<" "<<#z<<"="<<(z)<<endl;
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS = 1e-9 ;
/*  ////////////////////////   C o d i n g  S p a c e   ////////////////////////  */
const int MAXN = 1000 + 9 ;
//第i条边的两个端点u v和权值w 和比较的辅助函数r
int u[MAXN],v[MAXN],w[MAXN],r[MAXN];
//并查集p
int p[MAXN];
int n,m;
int cmp(const int i,const int j){ return w[i]<w[j];}
int find(int x){ return p[x]==x?x:p[x]=find(p[x]);}
int Kruskal(){ 
    int ans=0;
    for (int i=0;i<n;i++) p[i]=i;
    for (int i=0;i<m;i++) r[i]=i;
    PIar(r,m)
    sort(r,r+m,cmp);
    PIar(r,m)
    for (int i=0;i<m;i++){
        int e=r[i];
        int x=find(u[e]);
        int y=find(v[e]);
        if (x!=y){
            ans+=w[e];
            p[x]=y;
        }
    }
    return ans;
}

void Solve()
{
    while(cin>>n>>m){
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u[i],&v[i],&w[i]);
        }
        printf("%d\n",Kruskal());
    }
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("1.in", "r", stdin);
    freopen("1.out","w",stdout);
#endif
//iostream::sync_with_stdio(false);
//cin.tie(0), cout.tie(0);
    // int T;cin>>T;while(T--)
    Solve();
    return 0;
}

以下是测试的数据:
输入
5 6
1 5 2
1 3 2
5 3 6
4 3 1
4 2 3
2 3 4
输出
0 1 2 3 4 5
3 0 1 4 5 2
8

posted @ 2016-10-31 17:12  s1124yy  阅读(196)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3