kruskal 算法

Kruskal 算法链表基本模板:

#include <iostream>
using namespace std;

typedef struct node
{
	int l;
	int r;
	int length;
	struct node *next;
}Node,*LNode;      // 定义结构体
void Init(LNode &L)   // 初始化结构体
{
	L=new Node;
	L->next=NULL;
	L->l=0;
	L->r=0;
	L->length=0;
}
//将权值 从小到大 插入链表。
void Create(LNode &L,int i,int j,int len) 
{
    Node *p,*g;
	p=L->next;
	g=L;
	while(p)
	{     
		if(len<p->length)
			break;
		g=p;
		p=p->next;
	}
	Node *q;
	q=new Node;
	q->next=g->next;
	q->length=len;
	q->l=i;
	q->r=j;
	g->next=q;
}


/*
void print(LNode L) // 是否排序
{
	Node *p;
	p=L->next;
	while(p)
	{
		cout<<p->length<<" ";
		p=p->next;
	}
	cout<<endl;
}*/
#define MAX 1000
int main()
{
	LNode L;
	
//	freopen("k.txt","r",stdin);
	int set[MAX];
	int n,i,j,e;
	while(cin>>n)
	{
		Init(L);
		for(i=1;i<=n;i++) // 将数组初始化
			set[i]=i;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
			{
				cin>>e;
				if(e && i>j)  //下三角形不为0时按顺序插入链表中
				{
					Create(L,i,j,e);
				}
			}
		//	print(L);
			int sum=0; // 边的总和
			Node *p;
			p=L->next;
			int v=0; //边数
			while(p)
			{
				//	print(L);
				int t1=p->l,t2=p->r;
				if(set[t1]!=set[t2]) 
				{
					int d=set[t1];  //  特别注意,这里要保存后在改变,被这里坑了好久。
						for(i=1;i<=n;i++)
							if(set[t1]==set[i])
							set[i]=set[t2];	
					for(i=1;i<=n;i++)
						if(d==set[i])
							set[i]=set[t1];
					sum+=p->length;
					v++;
					if(v==n-1)
						break;
				}
				p= p->next;
			}
			cout<<sum<<endl;
			
	}
	
	return 0;
}
/*
6
0 6 1 5 0 0
6 0 5 0 3 0
1 5 0 5 6 4
5 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0*/
/*
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0*/

借用大神代码:

 用结构体做的kruskal 算法

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

int n,k,Vexset[110];

struct P{
	int Head,Tail;
	int lowcost;
}Edge[11000];

bool cmp(P a,P b){
	return a.lowcost<b.lowcost;
}

void Kruskal(){
	sort(Edge,Edge+k,cmp);
	/*int i,j;
	for(i=0;i<k;i++)
	cout<<Edge[i].lowcost<<endl;
	*/
	int i,s=0,c=1;
	for(i=0;i<n;i++)
		Vexset[i]=i;
	for(i=0;i<k;i++){
		int vs1,vs2;
		vs1=Vexset[Edge[i].Head];
		vs2=Vexset[Edge[i].Tail];
		if(vs1!=vs2){
			//cout<<Edge[i].Head<<' '<<Edge[i].Tail<<endl;
			s+=Edge[i].lowcost;
			c++;
			if(c==n)
				break;
			for(int j=0;j<n;j++){
				if(Vexset[j]==vs2){
					Vexset[j]=vs1;
				}
			}
		}
	}
	cout<<s<<endl;
}
int main(){
	while(cin>>n){
		int i,j,d;
		k=0;
		for(i=0;i<n;i++){
			for(j=0;j<n;j++){
				cin>>d;
				if(i>j&&d){
					Edge[k].Head=i;
					Edge[k].Tail=j;
					Edge[k].lowcost=d;
					k++;
				}
			}
			
		}
		Kruskal();
	}
	return 0;
}


题目: http://poj.org/problem?id=1258


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值