现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
输入样例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
输出样例:
12
用了暴力的方法:用prim算法对每个顶点生成最小树,找出其最小的距离输出即可;只是第三个测试点没通过。。不知道为啥。。看半天好像也没毛病
#include<stdio.h>
#define inf 1010
#define INF 9999999
int N,M;
int G[inf][inf];
int dist[inf*3];
int vis[inf];
int sum;
void prim(int ret)//普莱姆最小生成树
{
int i,v,min,mini;
vis[ret]=1;//收录
for(i=1;i<=N;i++)
{
if(G[ret][i]!=inf)//有边
{
dist[i]=G[ret][i];
}
else
dist[i]=INF;
}
dist[ret]=0;
while(1)
{
mini=min=INF;
for(i=1;i<=N;i++)
{
if(vis[i]==0)
{
if(min>dist[i])
{
min=dist[i];//找个最小距离
mini=i;
}
}
}
v=mini;
if(v==INF)
break;
vis[v]=1;//收录
for(i=1;i<=N;i++)
{
if(G[v][i]>0&&vis[i]==0)//有边且没访问过
{
if(dist[i]>G[v][i])
{
dist[i]=G[v][i];//dist记录的是顶点和最小生成树的距离 也就是邻接点之间的距离
}
}
}
}
}
int main()
{
int i,j,x1,x2,x3,min=INF,sum,ret=0;
scanf("%d%d",&N,&M);
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
G[i][j]=G[j][i]=INF;
for(i=0;i<M;i++)
{
scanf("%d%d%d",&x1,&x2,&x3);
G[x1][x2]=G[x2][x1]=x3;
}
for(i=1;i<=N;i++)
{
sum=0;
prim(i);
for(j=1;j<=N;j++)
sum+=dist[j];
if(sum<INF)//小于INF则是表示每段距离被更新过,也就是连通了
ret++;
if(min>sum)
min=sum;
}
if(ret==N)
printf("%d",min);
else
printf("-1");
return 0;
}
测试点 | 提示 | 结果 | 分数 | 耗时 | 内存 |
---|---|---|---|---|---|
0 | sample换数字,各种回路判断 | 答案正确 | 15 | 5 ms | 308 KB |
1 | M<N-1,不可能有生成树 | 答案正确 | 2 | 4 ms | 180 KB |
2 | M达到N-1,但是图不连通 | 答案正确 | 2 | 5 ms | 320 KB |
3 | 最大N和M,连通 | 答案错误
| 0 | 32 ms | 4152 KB |
4 | 最大N和M,不连通 | 答案正确 | 6 | 25 ms | 4168 KB |