usaco-Agri-Net(MST)

题目类型:MST

题意:n个点给出邻接矩阵(对称),求MST。


算法:kruscal,prime。


kruscal,边操作,每次选最短边,如果两边连接的点不在同一集合,加入可用边,一直到n-1条为止。

优化:并查集的优化,priority_queue(或者预处理)


kruscal代码:(边少点多)

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

#define N 150
#define ffor(i, n) for(i=0; i<n; ++i)

struct node{
	int x, y, v;
	
	bool operator < (const node & tmp) 
	{	return v<tmp.v; }
};

int mat[N][N], fat[N], n;
vector<node> edge;

int find(int x){
	if(fat[x]==x) return x;
	else {
		fat[x]=find(fat[x]);
		return fat[x];
	}
}

void bing(int x, int y){
	fat[find(y)]=find(x);
}

int main()
{
	node tmp;
	int i, j, x, ans;

	while(~scanf("%d", &n)){
		ffor(i, n) ffor(j, n) scanf("%d", &mat[i][j]);
		
		edge.clear();
		ffor(i, n) ffor(j, i) { tmp.x=j; tmp.y=i; tmp.v=mat[i][j]; edge.push_back(tmp); }

		sort(edge.begin(), edge.end());
		ffor(i, N) fat[i]=i;	
		x=1; ans=0; 
		ffor(i, N*N) {
			if(x==n) break;
			tmp=edge[i];
			if(find(tmp.x)!=find(tmp.y)){
				x++;
				bing(tmp.x, tmp.y);
				ans+=tmp.v;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
9549269 1258Accepted376K16MSC++975B2011-11-10 21:05:43



prime, 点操作每次扩展用当前最短边扩展未加入集合的点,直到加入所有点。

优化,最短边的堆优化。


prime代码:边多点少

#include <stdio.h>

#define N 150
#define ffor(i, n) for(i=0; i<n; ++i)

const int inf=0x7fffffff;

int mat[N][N], lowc[N], vis[N];
int n;

int prim()
{
    int i, j, p, res, minc;

    for(i=1; i<n; ++i){
        vis[i]=0;
        lowc[i]=mat[0][i];
    }

    vis[0]=1;    res=0;

    for(i=1; i<n; ++i) {
        minc=inf;    p=-1;
        for(j=1; j<n; ++j) {
            if(!vis[j] && minc>lowc[j]){
                p=j;    minc=lowc[j];
            }
        }

        if(minc==inf) return -1;
        res+=minc;    vis[p]=1;

        for(j=1; j<n; ++j) {
            if(!vis[j] && lowc[j]>mat[p][j]){
                lowc[j]=mat[p][j];
            }
        }
    }

    return res;
}


int main()
{
	int i, j;

	while(~scanf("%d", &n)){
		ffor(i, n) ffor(j, n) mat[i][j]=inf;
		ffor(i, n) ffor(j, n) scanf("%d", &mat[i][j]);
		printf("%d\n", prim());
	}
	return 0;
}
9549364 1258Accepted228K16MSC++930B2011-11-10 21:25:09


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值