考查点:最小生成树
小感:
提交情况:一次AC
AC_Code:
- #include <iostream>
- #define MAX 27
- #define MAXCOST 101
- using namespace std;
- int vertices[MAX],lowcost[MAX],minv,totalcost;
- int edges[MAX][MAX];
- bool visited[MAX];
- int prim(int vertex_num,int v)
- {
- totalcost=0;
- visited[v]=true;
- for(int i=0;i<vertex_num;i++)
- lowcost[i]=edges[v][i];
- for(int i=1;i<vertex_num;i++)
- {
- minv=MAXCOST;
- //for选出从U中顶点到V-U中顶点的最小权值,每次从第一个开始
- //这样如果碰到边界顶点时,可以回到另外的点
- for(int j=0;j<vertex_num;j++)
- if(visited[j]==false&&lowcost[j]<minv)//lowcost[j]是从顶点v到顶点j的权值
- {
- minv=lowcost[j];
- v=j;
- }
- visited[v]=true;
- totalcost+=minv;
- for(int j=0;j<vertex_num;j++)
- if(visited[j]==false&&edges[v][j]<lowcost[j])
- lowcost[j]=edges[v][j];
- }
- return totalcost;
- }
- int main()
- {
- int num,degree,cost;
- char vertex;
- while(cin>>num)
- {
- if(num==0) break;
- for(int i=0;i<num;i++) vertices[i]=i;
- for(int i=0;i<num;i++)
- for(int j=0;j<num;j++)
- edges[i][j]=MAXCOST;
- for(int i=0;i<num;i++) visited[i]=false;
- for(int i=0;i<num-1;i++)
- {
- cin>>vertex>>degree;
- for(int j=0;j<degree;j++)
- {
- cin>>vertex>>cost;
- edges[i][vertex-'A']=cost;
- edges[vertex-'A'][i]=cost;
- }
- }
- cout<<prim(num,0)<<endl;
- }
- return 0;
- }
第一次做图论题目,而且一次就AC了,挺兴奋的,呵呵。当然,还有很多不是非常明白的地方,对算法很细节的执行还没有非常明白~还有就是,Prim算法的过程好像是选出一个点后,找该点与剩下的点的权值的最小值,而不是所有在U中的点与V-U中的点的最小值。开始时觉得应该是所有U中的与V-U中最小的值的~还得再看看~
这里用了Prim求最小生成树,图是用邻接矩阵表示的,算法复杂度为O(n
2),其实看书上的例子,是用邻接表实现的,而且用到了最小堆求权值最小的边,最后的复杂度为O(elog
2e),e为边数。总的过程是从V-U中选出到U中权值最小的点,并加到U,之后更新lowcost,被更新的lowcost只是在V-U中的。
还有就是关于scanf,开始时用,可是在输入的时候有问题,不知道怎么回事~看别人也都说scanf会RE等的,于是用了cin,结果0MS就可以过了~还有,也看到有人说用了26时,RE了,所以我就改成27了,也不知道26到底会不会错~