题目意思
给你n个村庄,再给你每个村庄之间的距离,现在给你Q条路。现在要将所有的村庄连通,问最短还要修多长的路。
解题思路
这就是一道简单的最小生成树问题。不过用kruskal算法写的时候,要注意判断所有村庄都联通是的结束条件,因为这一点的问题,我还内存超了还几次呢。。。。
代码部分
kruskal算法
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
int n,sum,cnt;
int pre[110],rank1[110];
int maps[110][110];
struct node
{
int from;
int to;
int weight;
} edge[110*110];
bool cmp(node a,node b)
{
return a.weight<b.weight;
}
int add(int u,int v,int w)
{
edge[cnt].from=u;
edge[cnt].to=v;
edge[cnt].weight=w;
cnt++;
}
int Find(int x)
{
if(pre[x]==x)
return x;
return pre[x]=Find(pre[x]);
}
int join(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(rank1[fx]>=rank1[fy])
{
pre[fy]=fx;
rank1[fx]+=rank1[fy];
}
else
{
pre[fx]=fy;
rank1[fy]+=rank1[fx];
}
}
int kruskal()
{
sort(edge,edge+cnt,cmp);
sum=0;
for(int i=0; i<cnt; i++)
{
if(Find(edge[i].from)==Find(edge[i].to))
continue;
else
{
join(edge[i].from,edge[i].to);
sum+=edge[i].weight;
}
}
return sum;
}
int main()
{
int q,a,b;
int w;
while(~scanf("%d",&n))
{
cnt=0;
for(int i=1; i<=n; i++)
{
pre[i]=i;
rank1[i]=1;
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d",&w);
add(i,j,w);
}
}
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&a,&b);
join(a,b);
}
//sum=0;
kruskal();
printf("%d\n",sum);
}
return 0;
}
prim算法
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int n,sum;
int maps[110][110],dis[110],vis[110];
void prim()
{
int i;
for(i=1; i<=n; i++)
{
dis[i]=maps[1][i];
vis[i]=0;
}
dis[1]=0;
vis[1]=1;
int j,k,tmp;
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;
}
}
if(tmp==inf)
break;
vis[k]=1;
sum+=dis[k];
for(j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]>maps[k][j])
dis[j]=maps[k][j];
}
}
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d",&maps[i][j]);
}
}
int q,a,b;
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&a,&b);
maps[a][b]=maps[b][a]=0;
}
sum=0;
prim();
printf("%d\n",sum);
}
return 0;
}