ZOJ 2966 Build The Electric System
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2966
模板题,直接贴代码
Prim算法
设图G =(V,E),其生成树的顶点集合为U。
①、把v0放入U。
②、在所有u∈U,v∈V-U的边(u,v)∈E中找一条最小权值的边,加入生成树。
③、把②找到的边的v加入U集合。如果U集合已有n个元素,则结束,否则继续执行②。
#include<string.h>
const int inf=99999;
int map[501][501];
void Prim(int n)
{
int i,j,min_i,min,sum=0;
int dis[501];
int vis[501];
for(i=0;i<n;i++)
dis[i]=map[i][0];
memset(vis,false,sizeof vis);
vis[0]=true;
for(i=1;i<n;i++)
{
min=inf,min_i=i;
for(j=1;j<n;j++)
{
if(vis[j]==false && dis[j]<min)
{
min=dis[j];
min_i=j;
}
}
if(min==inf)
break;
sum+=min;
vis[min_i]=true;
for(j=1;j<n;j++)
{
if(vis[j]==0 && dis[j]>map[min_i][j])
dis[j]=map[min_i][j];
}
}
printf("%d\n",sum);
}
int main()
{
int t,n,m;
int a,b,k,j,i;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
map[i][j]=map[j][i]=inf;
for(i=0;i<m;i++)
{
scanf("%d %d %d",&a,&b,&k);
map[a][b]=map[b][a]=k;
}
Prim(n);
}
}
return 0;
}
Kruskal 算法
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=99999;
int father[501];
struct edge
{
int x,y,v;
};
struct edge ed[100010];
bool cmp(edge a,edge b)
{
return a.v<b.v;
}
int find(int x)
{
if(x==father[x])
return x;
return father[x]=find(father[x]);
}
void kruskal(int n,int m)
{
int i,fx,fy;
int ans=0;
for(i=0;i<n;i++)
father[i]=i;
sort(ed,ed+m,cmp);//对边的排序
for(i=0;i<m;i++)
{
fx=find(ed[i].x);
fy=find(ed[i].y);
if(fx!=fy)
{
ans+=ed[i].v;
father[fx]=fy;
}
}
printf("%d\n",ans);
}
int main()
{
int t,n,m;
int a,b,k,i;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%d %d",&n,&m);
for(i=0;i<m;i++)
{
scanf("%d %d %d",&a,&b,&k);
ed[i].x=a,ed[i].y=b,ed[i].v=k;
}
Krusal(n,m);
}
}
return 0;
}