您的位置:首页 > 其它

最小生成树问题

2017-08-14 19:38 253 查看

一:nyoj38http://acm.nyist.net/JudgeOnline/problem.php?pid=38

prim算法:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int low[510],map[510][510],vis[510],v;//全局变量
int prime(){
int min,pos,i,j,k,result=0;
memset(vis,0,sizeof(vis));
pos=1;vis[1]=1;
for(i=1;i<=v;++i){
if(i!=pos)low[i]=map[pos][i];
}
for(j=1;j<v;++j){
min=inf;
for(i=1;i<=v;++i){
if(!vis[i]&&min>low[i]){
min=low[i];pos=i;
}
}
//printf("%d\n",min);
result+=min;vis[pos]=1;
for(i=1;i<=v;++i){
if(!vis[i]&&low[i]>map[pos][i])
low[i]=map[pos][i];
}
}
return result;
}
int main()
{
int n,k,i,j,a,b,min,e,c;
scanf("%d",&k);
while(k--){
memset(map,0x3f,sizeof(map));//初始化为int数据的最大值
scanf("%d%d",&v,&e);
while(e--){
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=c;
}
min=inf;//无穷
for(i=0;i<v;++i){
scanf("%d",&a);
if(a<min)min=a;
}
min=min+prime();
printf("%d\n",min);
}
return 0;
} kruskal算法:
#include<stdio.h>
#include<algorithm>
using namespace std;
struct stu
{
int s;
int u;
int w;
}vt[130000];
int per[510];
int cross[510];
int cmp1(stu a,stu b)
{
return a.w<b.w;
}
int cmp2(int a,int b)
{
return a<b;
}
int find(int x)
{
return x==per[x]?x:per[x]=find(per[x]);
}
bool join(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
per[fx]=fy;
return true;
}
else return false;
}
int main()
{
int t,i,v,e;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&v,&e);
for(i=0;i<e;i++)
scanf("%d%d%d",&vt[i].s,&vt[i].u,&vt[i].w);
for(i=0;i<v;i++)
{
scanf("%d",&cross[i]);
per[i]=i;
}
per[i]=i;
int sum=0;
int flag=0;
sort(vt,vt+e,cmp1);
for(i=0;i<e;i++)
{
if(join(vt[i].s,vt[i].u))
{
flag++;
sum+=vt[i].w;
}
if(flag==v-1)break;
}
sort(cross,cross+v,cmp2);
sum+=cross[0];
printf("%d\n",sum);
}
return 0;
}


参考博客:http://blog.csdn.net/mblhq/article/details/47446869

二:hdu:1233http://acm.hdu.edu.cn/viewcode.php?rid=21723629

prime算法:

#include<iostream>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int map[110][110],vis[110],low[110],v;
int prime()
{
int min,pos,ans=0;
memset(vis,0,sizeof(vis));
pos=1;vis[1]=1;
for(int i=1;i<=v;i++)
if(!vis[i])
low[i]=map[pos][i];
for(int j=1;j<v;j++)
{
min=inf;
for(int i=1;i<=v;i++)
if(!vis[i]&&min>low[i]){
min=low[i];pos=i;
}
ans+=min;vis[pos]=1;
for(int i=1;i<=v;i++)
{
if(!vis[i]&&low[i]>map[pos][i])
low[i]=map[pos][i];
}
}
return ans;

}
int main()
{
int a,b,c,t;
while(cin>>v)
{
if(v==0)
break;
memset(map,0,sizeof(map));
t=v*(v-1)/2;
for(int i=0;i<t;i++)
{
cin>>a>>b>>c;
map[a][b]=map[b][a]=c;
}
cout<<prime()<<endl;
}
}


kruskal算法:
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10005;
struct node { int from,to,len;} edge[maxn];//储存边的数据结构
int n,fa[maxn],m,ans,q;
bool cmp(node a,node b) { return a.len<b.len; }//边按从小到大的顺序排列
int Find(int x)
{
if(fa[x]==x) return x;
return fa[x]=Find(fa[x]);
}
void Merge(int x,int y)
{
x=Find(x),y=Find(y);
if(x!=y) fa[y]=x;
}
int kruskal()
{
sort(edge,edge+m,cmp);//边排序
for(int i=0;i<=n;i++) fa[i]=i;//初始化并查集
ans=0;
for(int i=0;i<m;i++)//一条边的两个端点不在同一个集合,则选它,并合并端点
if(Find(edge[i].from)!=Find(edge[i].to)) Merge(edge[i].from,edge[i].to),ans+=edge[i].len;
return ans;
}
int main()
{
while(cin>>n,n)
{
m=n*(n-1)/2;
for(int i=0;i<m;i++) cin>>edge[i].from>>edge[i].to>>edge[i].len;
cout<<kruskal()<<endl;
}
return 0;
}

还有一种并查集+快排       来源:http://www.2cto.com/kf/201308/234398.html

#include"algorithm"
#include<stdio.h>
using namespace std;

struct node
{
int x,y,z;
}a[10000];

int cmp(node a,node b)
{
return a.z<b.z;
}

int pre[100000];
int find(int k)
{
if(k==pre[k])
return k;
pre[k]=find(pre[k]);
return pre[k];
}

int main()
{
int m,i,ans,f1,f2,n;
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
pre[i]=i;
m=(n-1)*n/2;
for(i=0;i<m;i++)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
sort(a,a+m,cmp);
ans=0;
for(i=0;i<m;i++)
{
f1=find(a[i].x);
f2=find(a[i].y);
if(f1!=f2)
{
pre[f1]=f2;
ans+=a[i].z;
}
}
printf("%d\n",ans);
}
return 0;
}


最小生成树的参考博客:http://www.cnblogs.com/xl1027515989/p/3597091.html

kruskal(克鲁斯卡尔)算法和prim(普里姆)算法参考博客:http://blog.csdn.net/weinierbian/article/details/8059129/

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

http://www.2cto.com/kf/201603/496259.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: