您的位置:首页 > 其它

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

2017-08-28 21:07 417 查看
题目链接: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;

v
f20e
oid 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: