问题描述
农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了使花费最少,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000
输入格式
第一行: 农场的个数,N(3<=N<=100)。
第二行..结尾: 接下来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们每行限制在80个字符以内,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为线路从第i个农场到它本身的距离在本题中没有意义。
输出格式
只有一个输出,是连接到每个农场的光纤的最小长度和。
样例输入
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
样例输出
28
直接prim好吧
#include<bits/stdc++.h>
using namespace std;
int pos[105][105],dis[105],vis[105],n,inf=0x3f3f3f3f,i,j;
int prim(){
memset(dis,inf,sizeof dis);
int res=0;
for(i=0;i<n;i++){
int t=-1;
for(j=1;j<=n;j++){
if(!vis[j]&&(t==-1||dis[j]<dis[t])){
t=j;
}
}
if(i&&dis[t]==inf){
return inf;
}
if(i){
res+=dis[t];
}
vis[t]=1;
for(j=1;j<=n;j++){
dis[j]=min(dis[j],pos[t][j]);
}
}
return res;
}
int main(){
cin>>n;
for(i=0;i<=n;i++){
for(j=0;j<=n;j++){
pos[i][j]=(i==j? 0:inf);
}
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
cin>>pos[i][j];
}
}
cout<<prim();
//标准普莱姆算法
}
//普莱姆算法模板:
/*
#include<iostream>
#include<cstring>
using namespace std;
const int N=510;
int g[N][N],dist[N],n,m;
bool st[N];
int ret=0;
int prim(){
memset(dist,0x3f3f3f3f,sizeof dist);
for(int i=0;i<n;i++){
int t=-1;
for(int j=1;j<=n;j++){
if(!st[j]&&(t==-1||dist[t]>dist[j])){
t=j;
}
}
if(i&&dist[t]==0x3f3f3f3f) {
return 0x3f3f3f3f;
}
st[t]=true;
if(i>0){
ret+=dist[t];
}
for(int j=1;j<=n;j++){
dist[j]=min(dist[j],g[t][j]);
}
}
return ret;
}
int main(){
memset(g,0x3f,sizeof g);
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=min(g[a][b],c);
}
int t=prim();
if(t==0x3f3f3f3f){
cout<<"impossible";
}else{
cout<<t;
}
}
*/