最小生成树问题
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
相关文章推荐
- 【分块答案】【最小生成树】【kruscal】bzoj1196 [HNOI2006]公路修建问题
- (精)(图论加强)布线问题(最小生成树)
- 图论, 1.各种方案的最短路径,最小生成树,拓扑排序, 2.隐式图的搜索,N-皇后问题,数独,马踏棋盘,中文划分,回文划分.
- poj 1251 丛林中的路 最小生成树问题 克鲁斯卡方法 并查集解决
- LuoguP2323 [HNOI2006]公路修建问题 【最小生成树+二分】By cellur925
- poj 2728 最优比率树(最小生成树问题)
- HDOJ1102 修路问题(最小生成树-Prim)
- HDU 1875 畅通工程再续 最小生成树问题
- Agri-Net(prim算法,最小生成树问题)
- 最小生成树问题
- 【图论】最短路径&&最小生成树问题
- POJ 1789 Truck History (prim解决最小生成树问题)
- 最小生成树问题用Prim算法或Kruskal算法
- 【最小生成树】BZOJ 1196: [HNOI2006]公路修建问题
- 遗传算法解决TSP问题实现以及与最小生成树的对比
- 最小生成树问题
- Nyoj 38 布线问题[最小生成树(Prim&&Kruscal)]
- 图论中最小生成树的问题学习
- 图论, 1.各种方案的最短路径,最小生成树,拓扑排序, 2.隐式图的搜索,N-皇后问题,数独,马踏棋盘,中文划分,回文划分.
- 并查集+排序 的最长木材问题 求最小生成树的最大边权值问题