题目连接:https://vjudge.net/problem/47584/origin
题目大意:有块岛屿,岛屿上有发电站和城市,两两城市架设电线,求最少用多长电线。
解题思路:最小生成树套模板就水过了~。
最小生成树:一个包含所有点并使得所有连接点的边的权值最小。
Prim算法知识点:任意一点的所有边中,权值最小的边包含于最小生成树中。
详释博客:https://blog.csdn.net/qq_35644234/article/details/59106779
ac代码:
1 #include<iostream> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 struct point{ 6 int y,z; 7 }; 8 int visit[1005]; 9 int main() 10 { 11 int n; 12 while(cin>>n) 13 { 14 int count=1; 15 while(n--) 16 { 17 vector<int> num; 18 vector<point> ay[1005]; 19 int x,y,z,a,b,c,sd,min,ans=0; 20 point now,next; 21 memset(visit,0,sizeof(visit)); 22 cin>>a>>b>>c; 23 for(int i=1;i<=c;i++) 24 { 25 cin>>sd; 26 num.push_back(sd); 27 visit[sd]=1; 28 } 29 for(int i=1;i<=b;i++) 30 { 31 cin>>x>>y>>z; 32 now.y=y;now.z=z; 33 ay[x].push_back(now); 34 now.y=x;now.z=z; 35 ay[y].push_back(now); 36 } 37 while(num.size()<a)//Prim算法 38 { 39 min=99999999; 40 for(int i=0;i<num.size();i++)//遍历当前点的集合 41 for(int j=0;j<ay[num[i]].size();j++)//遍历当前点所有的边 42 { 43 if(!visit[ay[num[i]][j].y]&&ay[num[i]][j].z<=min)//当可扩点未访问且权值小于当前发现最小的权值边 44 { 45 next.y=ay[num[i]][j].y; 46 min=next.z=ay[num[i]][j].z; 47 } 48 } 49 visit[next.y]=1; 50 num.push_back(next.y);//该点加入点集合 51 ans+=next.z;//总长度增加 52 // cout<<"#"<<ans<<" "<<next.y<<" "<<next.z<<endl; 53 } 54 cout<<"Case #"<<(count++)<<": "<<ans<<endl; 55 //for(int i=0;i<num.size();i++) 56 //cout<<num[i]<<" "; 57 //cout<<endl; 58 } 59 } 60 return 0; 61 }