hdu1233还是畅通工程

http://acm.hdu.edu.cn/showproblem.php?pid=1233

/*********************最小生成树之kruskal算法**********************
// Kruskal.cpp : Defines the entry point for the console application. 
*******************************************************************/

#define MAX_VERTEX_NUM 105 
#define INFINITY 0x11111111 
#define TRUE 1 
#define FALSE 0 

typedef struct{ 
    int set; // 顶点所在集合的编号 
    //int info; 
}VertexType; 

typedef struct{ 
    int val; 
    int flag; // 边的使用标记 
    //int info; 
}ArcType,ArcMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 

typedef struct{ 
    int vexnum; 
    VertexType vexs[MAX_VERTEX_NUM]; 
    ArcMatrix arcs; 
}MGraph; 

#include <string> 
#include <iostream> 
using namespace std; 

// 基于图的并查集操作 
// ==============查 
int findx(MGraph &G, int x) 
{ 
    int i,j; 
    int r = x; 
    while (G.vexs[r].set != r) //循环结束,则找到根节点 
        r = G.vexs[r].set;        
    i = x; 
    while (i != r) //本循环修改查找路径中所有节点 
    {    
        j = G.vexs[i].set; 
        G.vexs[i].set = r; 
        i = j; 
    } 
    return r; 
} 
// ==============并 
void merge(MGraph &G, int x,int y) 
{ 
    int fx,fy; 
    fx = findx(G,x); 
    fy = findx(G,y); 
    if(fx != fy) 
        G.vexs[fx].set = fy; 
} 

int MiniSpanTree_Kruskal(MGraph &G) { 
    int i,j,k; 
    int mj,mk; 
    int summiniw=0;
    // 初始化集合信息、边的标记值 
    for (i=0;i<G.vexnum;i++) G.vexs[i].set=i,G.arcs[i][i].flag=0; 

    for (i=1;i<G.vexnum;i++) // n-1 次 取边 
    { 
        mj=0; mk=0; 
        for (j=0;j<G.vexnum;j++) 
            for (k=0;k<G.vexnum;k++) 
            { 
                 if (G.arcs[j][k].flag==INFINITY && findx(G,j)!=findx(G,k)) // 对未做标记且顶点不在同一个集合的边操作
                   if ( (mj==0 && mk==0) ||G.arcs[j][k].val<G.arcs[mj][mk].val ) // 最小的边
        mj=j,mk=k; 
            } 
        // 合并顶点集合、标记使用过的边 
        merge(G,mj,mk); G.arcs[mj][mk].flag = G.arcs[mk][mj].flag = 0; 
        // ***************************************************************
             //   cout<<mj+1<<"-"<<mk+1<<": "<<G.arcs[mj][mk].val<<endl; //
        summiniw+=G.arcs[mj][mk].val;
        //*******************************************************************
    } 
    return summiniw; 
} 

int main(int argc, char* argv[]) 
{ 
    MGraph g; 

    int n,m; 
    int x,y,z; 
    int i;      
    while(scanf("%d",&n)!=EOF&&n)
    {
        g.vexnum = n; 
        memset(g.arcs,INFINITY,sizeof(g.arcs)); 
        m=n*(n-1)/2;
        for(i=0;i<m;i++) 
        { 
            cin>>x>>y>>z; 
            x--,y--; 
            g.arcs[x][y].val = z; 
            g.arcs[y][x].val = z; 
        } 
        printf("%d\n",MiniSpanTree_Kruskal(g)); 
    }
    return 0; 
} 

/************************************************************************ 

6 10 
1 2 6 
1 3 1 
1 4 5 
2 3 5 
2 5 3 
3 4 5 
3 5 6 
3 6 4 
4 6 2 
5 6 6 
   
************************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值