最小生成树

来源:互联网 发布:python全栈 编辑:程序博客网 时间:2024/06/09 20:41

最小生成树(n个结点的连通图最小权重)

1.Prim算法(对点的选取加入)

用二维数组记录点和权值。先选取一个点作起始点,然后任选一个邻近未访问过的权值最小点,重复直到选出n个点。

#define INF 0x7FFFFFFFint w[510][510];int v[510],low[510];//low[i]记录当前在S内, 未访问点到点i的最小距离int main(){int t,n,maxx,sum;bool first = true;    cin >> t;while(t--) {cin>>n;sum = maxx = 0;memset(v,0,sizeof(v));for(int i=1;i<=n;i++)  for(int j=1;j<=n;j++)  cin>>w[i][j];  //邻接矩阵           v[1] = 1; //从点1开始,初始化设离点i最近的点是点1for(int i=2;i<=n;i++) low[i] = w[1][i];for(int i=1;i<n;i++){int x=1, m=INF; for(int j=1;j<=n;j++)//找出未访问的最小low[j]点x  if(!v[j]&&low[j]<m){    x = j;    m = low[j];  }v[x] = 1;sum += m;if(maxx<m) maxx = m;for(int j=2;j<=n;j++){ //更新未访问点到点i的最短边  if(!v[j]&&low[j]>w[x][j])low[j] = w[x][j]; } }if(first) first=false;else cout<<endl;cout << maxx << " "<< sum<<endl;}  //sum为最小生成树总长度,maxx为其中的最长边     return 0;}  


2.kruskal算法(对边的选择)

将所有边按权值从小到大排序,从权值最小边开始遍历每条边,直至图中所有节点都在同一个连通分量中

#define N 510int father [N];struct point{    int x,y,len;}pot[N*N];int cmp(point x,point y){    return x.len<y.len;}int find(int x){  //使用并查集    while(x!= father [x])      x= father [x];    return x;}int main(){int t,n,maxx,sum,a,b;    cin >> t;while(t--) {cin>>n;sum = maxx = 0;int q = 0;for(int i=1;i<=n;i++)  for(int j=1;j<=n;j++){   cin>>pot[q].len;   pot[q].x = i;   pot[q++].y = j;  }         sort(pot,pot+q,cmp);       for(int i=1;i<=n;i++) father[i]=i;             for(int i=0;i<q;i++) //遍历选边       {           a = find(pot[i].x);           b = find(pot[i].y);           if(a!=b){  //不连接成环就加入此边                sum += pot[i].len;             if(pot[i].len>maxx)                maxx=pot[i].len;             father [b]=a;            }        }cout <<sum<<" "<< maxx <<endl;}      return 0;}  



0 0