第一题:
这里讨论最小生成树问题,最小生成树是原图的一个子图,其中包含所有节点,仅含有部分边,使得这个子图为连通图,且不含有环路,并且边上的权值和最小,则称为最小生成树。
思路: 这道题用克鲁斯卡尔的方法来求最小生成树:
如上图:我们需要两种数据结构,一个是用来确定两个点是否属于一个集合,另一个是我们要将边的权值进行排序,需要一个struct来存储边,并且用到了重载小于号,使用sort快排。
代码如下:
#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 101
int Tree[N];
int findRoot(int x){
if(Tree[x]==-1)return x;
else{
int tmp=findRoot(Tree[x]);
Tree[x]=tmp;
return tmp;
}
}
struct Edge{
int a,b;
int cost;
bool operator<(const Edge &A)const{
return cost<A.cost;
}
}edge[6000];
int main(){
int n;
freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF&&n!=0){
for(int i=1;i<=n*(n-1)/2;i++){
scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].cost);
}
sort(edge+1,edge+1+n*(n-1)/2);
for(int i=1;i<=n;i++){
Tree[i]=-1;
}
int ans=0;
for(int i=1;i<=n*(n-1)/2;i++){
int a=findRoot(edge[i].a);
int b=findRoot(edge[i].b);
if(a!=b){
Tree[a]=b;
ans+=edge[i].cost;
}
}//注意,最小生成树,要求全图连通,因为题目中给出,是个完全图。所以不用考察连通分量的问题
printf("%d\n",ans);
}
return 0;
}
第二题:
来源:CSDN
作者:猪猪传奇
链接:https://blog.csdn.net/qq_42127861/article/details/104620238