HDU1102 Constructing Roads 最小生成树prim||kruskal

52 篇文章 0 订阅
12 篇文章 0 订阅

题目链接:HDU1102

很裸的题目,下面给出prim算法和kruskal算法解题代码,直接套模板即可。

AC代码:

prim()算法

/*
2017年8月28日15:57:26
HDU1102
最小生成树 
prim算法
AC 
*/
#include <iostream>
//#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector> 
using namespace std;
const int inf=1<<29;
const int maxn=110;
bool vis[maxn]; 
int dis[maxn]; 
int map[maxn][maxn];
int n,a,b,q; 
void prim(){    
    int i,j,k,tmp,ans=0;    
    for(i=1;i<=n;i++){
    	dis[i]=inf;//初始化     
    	vis[i]=false;
	}    
    	
    dis[1]=0;    
    for(i=1;i<=n;i++){    
        tmp=inf;    
        for(j=1;j<=n;j++){    
            if(!vis[j]&&tmp>dis[j]){    
                tmp=dis[j];    
                k=j;    
            }//找出最小距离的节点     
        } 
		ans+=dis[k];   
        vis[k]=1;//把访问的节点做标记    
        for(j=1;j<=n;j++){    
            if(!vis[j]&&dis[j]>map[k][j])    
            dis[j]=map[k][j];//更新最短距离     
        }    
    }    
    printf("%d\n",ans);
}    

void init(int n){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%d",&map[i][j]);
		}
	}
	scanf("%d",&q);
	for(int i=1;i<=q;i++){
		scanf("%d%d",&a,&b);
		map[a][b]=map[b][a]=0;
	}
} 

void solve(){
	prim();
}
int main(){
	while(~scanf("%d",&n)){
		init(n);
		solve();
	}
	return 0;
} 


kruskal算法:


/*
2017年8月28日21:05:19
HDU1102
最小生成树
kruskal算法 
AC
*/
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector> 
using namespace std;
const int maxn=1e4+10;
struct node{
	int u,v,w;
	void init(){
		u=v=w=0;
	}
}edge[maxn];
int pre[maxn];
int n,w,num,a,b,q;


void addedge(int u,int v,int w){
	edge[num].u=u;
	edge[num].v=v;
	edge[num].w=w;
	num++; 
} 

bool cmp(node a,node b){
	return a.w<b.w;
}
int find(int x){  
    int r=x;  
    while(pre[r]!=r)    r=pre[r];//查找到根节点为止   
    int i=x,j;  
    while(i!=r){  
        j=pre[i];  
        pre[i]=r;  
        i=j;  
    }  
    return r;   
}

int kruskal(int n){
	int ans=0;
//	int cnt=0;
	sort(edge,edge+num,cmp);
	for(int i=0;i<num;i++){
		int u=edge[i].u;
		int v=edge[i].v;
		int w=edge[i].w;
		u=find(u);
		v=find(v);
		if(u!=v){
			ans+=w;
			pre[v]=u;
		//	cnt++;
		}
	}
	return ans;
}

void init(){
	for(int i=1;i<=maxn;i++) edge[i].init();
	for(int i=1;i<=n;i++) pre[i]=i;
	num=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%d",&w);
			if(i>=j) continue;
			else addedge(i,j,w);
		}
	}
	scanf("%d",&q);
	for(int i=1;i<=q;i++){
		scanf("%d%d",&a,&b);
		a=find(a);
		b=find(b);
		pre[b]=a;
	}
}
void solve(){
	printf("%d\n",kruskal(n)); 
}
int main(){

	while(~scanf("%d",&n)){
		init();
		solve();
	}
	return 0;
} 


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值