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