题目描述 Description
一个国家有n个城市。若干个城市之间有电话线连接,现在要增加m条电话线(电话线当然是双向的了),使得任意两个城市之间都直接或间接经过其他城市有电话线连接,你的程序应该能够找出最小费用及其一种连接方案。
输入描述 Input Description
输入文件的第一行是n的值(n<=100).
第二行至第n+1行是一个n*n的矩阵,第i行第j列的数如果为0表示城市i与城市j有电话线连接,否则为这两个城市之间的连接费用(范围不超过10000)。
输出描述 Output Description
输出文件的第一行为你连接的电话线总数m,第二行至第m+1行为你连接的每条电话线,格式为i j,(i < j) , i j是电话线连接的两个城市。输出请按照Prim算法发现每一条边的顺序输出,起始点为1.
第m+2行是连接这些电话线的总费用。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=99999999;
int a[105][105];
bool bo[105];
int jl[105];
int n;
int ans=0;
int bj[105];
int QAQ=0;
int b[105],c[105];
int main()
{
memset(bo,0,sizeof(bo));
memset(jl,inf,sizeof(jl));
scanf("%d",&n);
int m;
int cs=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
bo[cs]=1;
for(int i=2;i<=n;i++)
{
jl[i]=a[i][1];
bj[i]=1;
}
for(int j=1;j<=n;j++)
{
int minn=inf;
for(int i=2;i<=n;i++)
{
if(bo[i]==1)
continue;
if(jl[i]<minn)
{
minn=jl[i];
cs=i;
}
}
if(minn==inf)
break;
bo[cs]=1;
ans+=minn;
if(minn!=0)
{
QAQ++;
b[QAQ]=min(bj[cs],cs);
c[QAQ]=max(bj[cs],cs);
}
for(int i=2;i<=n;i++)
{
if(bo[i]==1)
continue;
if(a[i][cs]<jl[i])
{
jl[i]=a[i][cs];
bj[i]=cs;
}
}
}
cout<<QAQ<<"\n";
for(int i=1;i<=QAQ;i++)
{
cout<<b[i]<<" "<<c[i]<<"\n";
}
cout<<ans;
return 0;
}