最小生成树拓展

对于一个连通图,输出最多能删除多少条边,使这个图仍连通。

Input:  N M //N—顶点数,M—边数

          v1 v2

          …… //M 行

Output:  删除的边个数及各边

这是几天前老师给我们讲了最小生成树后出的一道题,留给大家思考并求解。)

  解题思路:连通图是个不带权的无向图,而有向图是强连通图(若非老师提醒,大家都迷糊了)。其中删除的边数很容易求出,不需要后面的M行边的输入,直接就可以求出是M-(N-1),要使这个图仍连通所需要的最少的边是顶点数减1,即最小生成树。关键就是怎样求这些要删除的边,我知道还是要用到最小生成树的算法,老师的一句话提醒了我们,可以把这个图的每条边权值都赋为1,然后再用普里姆(Prim)算法建立最小生成树。我就顺着这个思路开始敲代码,我把最小生成树中的边赋值为2,与可删除的边区分开来。当然开始把每两个顶点之间的距离初始化为最大值。最后输出距离为1的边就是要删除的边。可是还是有问题,我这个答案只是其中一个解,由于图中各边的权值相同,删除的边就不一定了,因为最小生成树并不唯一。(不过我还会寻找更好的解决方法。)

代码如下:

View Code
 1 #include<iostream>
 2 using namespace std;
 3 #define Max 100
 4 int map[Max][Max],n,m;
 5 struct{
 6     int adjvex;
 7     int lowcost;
 8 }closedge[Max];
 9 void prim(int k)//普里姆算法
10 {
11     int i,j;
12     for(j=1;j<=n;j++)
13         if(j!=k){ closedge[j].adjvex=k; closedge[j].lowcost=map[k][j]; }
14     closedge[k].lowcost=0;
15     for(i=1;i<n;i++)
16     {
17         int min=Max;
18         for(j=1;j<=n;j++)
19            if(closedge[j].lowcost!=0&&min>closedge[j].lowcost)
20            {
21                min=closedge[j].lowcost;
22                k=j;
23            }
24         map[closedge[k].adjvex][k]=map[k][closedge[k].adjvex]=2;//把最小生成树中的边赋值为2
25         cout<<closedge[k].adjvex<<""<<k<<endl;
26         closedge[k].lowcost=0;
27         for(j=1;j<=n;j++)
28            if(map[k][j]<closedge[j].lowcost)
29            {
30                closedge[j].adjvex=k;
31                closedge[j].lowcost=map[k][j];
32            }
33     }
34 }
35 int main()
36 {
37    int i,j,a,b;
38    cin>>n>>m;
39    for(i=1;i<=n;i++)//初始化
40    {
41       closedge[i].lowcost=Max;
42       for(j=1;j<=n;j++)
43           map[i][j]=Max;
44    }
45    for(i=0;i<m;i++)
46    {
47        cin>>a>>b;
48        map[a][b]=map[b][a]=1;
49    }
50    prim(1);
51    cout<<"最多删除的边的个数为:"<<m-(n-1)<<endl;
52    cout<<"删除的边为:"<<endl;
53    for(i=1;i<=n;i++)
54        for(j=1;j<i;j++)
55            if(map[i][j]==1) cout<<j<<""<<i<<endl;
56     return 0;
57 }

 

posted @ 2011-08-26 21:24  笑巧  阅读(315)  评论(0编辑  收藏  举报