zoukankan      html  css  js  c++  java
  • 克鲁斯卡尔算法+并查集

    算法要点:Kruskal算法的最难点在于怎样判断加入边(x,y)后是否形成了环。

    问题可化为:判断边(x,y)的两个顶点x,y在图(实际是森林)mst中最否已经连通。如果已经连通,加入边将形成环;否则,不形成环。

    在kruskal算法中,要用到并查集的合并和查找

    并查集:

     1 int getfa(int k)        //找到最祖先
     2 {
     3     if(fa[k]==k)    return k;
     4     fa[k]=getfa(fa[k]);
     5     return fa[k];
     6 }
     7 
     8 void merge(int x,int y)       //合并祖先
     9 {
    10     int fx=getfa(x);
    11     int fy=getfa(y);
    12     fa[fx]=fy;
    13 }
    14 
    15 bool judge(int x, int y)       //判断是不是一个祖先
    16 {
    17     int fx=getfa(x);
    18     int fy=getfa(y);
    19     return fx==fy;
    20 }

     kruskal算法核心:

     1 for(int i=1;i<=n;i++)
     2         fa[i]=i;
     3 sort(e+1,e+1+len,mys);
     4 int cal=0;
     5 for(int i=1;i<=len;i++)
     6 {
     7     int v=getfa(e[i].x);
     8     int u=getfa(e[i].y);
     9     if(v!=u)
    10     {
    11         merge(v,u);
    12                 //根据题意添加
    13         if(++cal==n-1)
    14         {
    15             break;
    16         }
    17     }
    18 }

    输入:

     1 int fa[maxn];
     2 int len=0;
     3 struct node
     4 {
     5     int x,y,v;
     6 }e[maxn];
     7 
     8 void init(int xx,int yy,int vv)
     9 {
    10     if(yy<0||yy>n*m)    return;
    11     e[++len].y=yy;
    12     e[len].x=xx;e[len].v=vv;
    13 }
    14 
    15 int main()
    16 {
    17     memset(e,0,sizeof(e));
    18     cin>>n>>m;
    19     for(int i=1;i<=m;i++)
    20     {
    21         int xx,yy,vv;
    22         cin>>xx>>yy>>vv;
    23         init(xx,yy,vv);
    24         init(yy,xx,vv);
    25     }
  • 相关阅读:
    eclipse中使用git
    获取系统的联系人信息
    Android中调用百度地图
    shell脚本等的操作
    shell与变量的声明的操作
    文件的基本操作命令
    Android实战_来电拦截专家
    linux c学习笔记----进程创建(fork,wait,waitpid)
    2.2.1 MySQL基本功能与参数文件管理
    2.3.6 Federate 远程访问数据库
  • 原文地址:https://www.cnblogs.com/zyker/p/5934922.html
Copyright © 2011-2022 走看看