poj-1258(Agri-Net)【图的最小生成树】
自学的数据结构,中午看到了图论的最小生成树,想着找个题巩固一下,找到了这个,结果一直错一直错,开始怀疑这本书的算法是不是有问题。。。,郁闷了一下午,晚上突然发现codevs上有这个题目,用了点办法截了一组错误数据,终于发现了错在哪,真是粗心呃。。。。。
#include <iostream> #include <cstdio> #define MAX 0x3f3f3f3f using namespace std; struct node { int start; int stop; int value; }; node x[110]; int y[110][110]; int n; void prime() { for (int i=0;i<n-1;++i) { x[i].start=0; x[i].stop=i+1; x[i].value=y[0][i+1]; } for (int i=0;i<n-1;++i) { int weight=MAX; int Min=i; for (int j=i;j<n-1;j++) { if (weight>x[j].value) { weight=x[j].value; Min=j; } } node temp; temp=x[i]; x[i]=x[Min]; x[Min]=temp; //cout<<x[i].start<<" "<<x[i].stop<<" "<<x[i].value<<endl; int vx=x[i].stop; for (int j=i+1;j<n-1;++j)//我感觉这个地方类似于贪心,从划给最小生成树的点中找到与未划入边的最小权值,当没加入时就一直保存这个值并比较,不用担心你加入的点是否还会产生另外未找到的与未加入点最小的权值 { int vy=x[j].stop; if (y[vx][vy]<x[j].value&&y[vx][vy]!=0) { x[j].start=vx; x[j].value=y[vx][vy]; } } } int all=0; for (int i=0;i<n-1;++i) { all+=x[i].value; } cout<<all<<endl; } int main() { while(cin>>n) { for (int i=0;i<n;++i) { for (int j=0;j<n;++j) { cin>>y[i][j]; } } prime(); } }
第二种算法,名字不会拼。。。。
#include <iostream> #define Max 0x3f3f3f3f using namespace std; struct node { int start; int stop; int value; }; node x[110]; int foot[110][110]; int n; int status[110]; int krsual() { int num=0; for (int i=0;i<n;++i) { status[i]=i; } while(num<n-1) { int weight=Max; int start,stop; for (int i=0;i<n-1;++i) { for (int j=i+1;j<n;++j) { if (weight>foot[i][j]) { weight=foot[i][j]; start=i; stop=j; } } } if (weight==Max) { return 0; } if (status[start]!=status[stop]) { x[num].value=weight; x[num].start=start; x[num].stop=stop; num++; } for (int j=status[stop],i=0;i<n;++i) { if (status[i]==j) { status[i]=status[start]; } } foot[start][stop]=Max; } } int main() { while(cin>>n) { for (int i=0;i<n;++i) { for (int j=0;j<n;++j) { cin>>foot[i][j]; } } krsual();//cout<<"OK"<<endl; int all=0; for (int i=0;i<n-1;++i) { all+=x[i].value; } cout<<all<<endl; } return 0; }