NYOJ38布线问题
首先,我们先了解一下Prim算法和Kruskal的区别;Prim最要是思想是根据顶点来得出结果,而Kruscal则是根据边来得出结果的,因此Prim最要运用于稠密图的计算,而Kruskal主要是运用于稀疏图的计算。而Prim和Kruskal在运行时间上也有较大的区别,Prim所需的时间较少(其实在实际应用中是Kruckal的用时较少的,但在NYOJ上的哪题不知道为嘛会Prim用时更少)。但两者也有共同之处,就是二者都是用到了贪心的思想,即总是将当前最小边加入到集合中。
Prim算法
#include<stdio.h>
#include<string.h>
#define INF 0x7fffffff
const int MAXN=502;
int graph[MAXN][MAXN];
int Prim(int n)
{
int lowcost[MAXN];
int i,j,minm,mind,ans=0;
for(i=2;i<=n;i++)
lowcost[i]=graph[1][i];
for(i=1;i<=n-1;i++)//n-1条边
{
minm=INF;
for(j=2;j<=n;j++)
if(lowcost[j]<minm&&lowcost[j]!=0)
{minm=lowcost[j];mind=j;}
ans+=minm;
lowcost[mind]=0;
for(j=2;j<=n;j++)
if(lowcost[j]>graph[j][mind]&&lowcost[j]!=0)
lowcost[j]=graph[j][mind];
}
return ans;
}
int main()
{
int T,i,e,v,a,b,w;
scanf("%d",&T);
while(T--)
{
memset(graph,127,sizeof(int));
scanf("%d%d",&v,&e);
for(i=1;i<=e;i++)
{
scanf("%d%d%d",&a,&b,&w);
graph[a][b]=graph[b][a]=w;
}
int cnt=Prim(v);
int minm=INF;
for(i=0;i<v;i++)
{
scanf("%d",&w);
if(minm>w)minm=w;
}
printf("%d\n",cnt+minm);
}
return 0;
}
Kruscal
#include<stdio.h>
#include<stdlib.h>
int f[550],sum=0;
void Father(void)
{
for(int i=1;i<505;i++)
f[i]=i;
}
struct Tree
{
int x;
int y;
int w;
}school[550000];
int cmp(const void *a,const void *b)
{
return(((Tree *)a)->w-((Tree *)b)->w);
}
void union_set(int x,int y,int sz)
{
f[x]=y;
sum+=sz;
}
int CMP(const void *a,const void *b)
{
return(*(int*)a-*(int*)b);
}
int main()
{
int n,housenum,inputnum,beside[55000];
scanf("%d",&n);
while(n--)
{
int i,x,y,count=0; sum=0; Father();
scanf("%d%d",&housenum,&inputnum);
for(i=0;i<inputnum;i++)
scanf("%d%d%d",&school[i].x,&school[i].y,&school[i].w);
qsort(school,inputnum,sizeof(school[0]),cmp);
for(i=0;i<inputnum;i++)
{ //printf("w=%d ",school[i].w);
for(x=school[i].x;x!=f[x];x=f[x])
f[i]=f[f[i]];
for(y=school[i].y;y!=f[y];y=f[y])
f[y]=f[f[y]];
if(x!=y)
{
union_set(x,y,school[i].w);
count++;
if(count==housenum) break;
}
}
for(i=0;i<housenum;i++)
scanf("%d",&beside[i]);
qsort(beside,housenum,sizeof(beside[0]),CMP); //printf("b=%d\n",beside[0]);
printf("%d\n",beside[0]+sum);
}
return 0;
}