对于一个连通图,输出最多能删除多少条边,使这个图仍连通。
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 }
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 }