您的位置:首页 > 其它

70.最小生成树

2016-03-12 22:58 288 查看
删边问题(edges.pas)

题目描述:连通图是指任意两个顶点都有路径可互相到达的图。

读入一个无向的连通图,输出最多能删掉多少条边,使这个图仍然连通。

输入格式:

第一行为图的顶点数N(1<=N<=100)和边数M,它们之间用一个空格隔开,图中的顶点用1到N的整数标号。接下来的M行,每行用两个数v1和v2表示一条边。v1和v2用一个空格隔开,表示这条边所连接的顶点的标号(v1<>v2),同一条边不会重复出现。

输出格式:

输出最多能删掉的边数。

输入输出样例:

输入edges.in

输出 edges.out

4 6

1 2

1 3

1 4

2 3

2 4

3 4

3

思路:寻找最小生成树,用总边数目减去最小生成树中的边的数目,直接用

总边数-n+1就行了

代码:

#include

#include

using namespace std;

#include

struct Edge{

int u,v,w,next;

};

Edge edge[1001];

int head[1001]={0},father[1001];

int visit[1001]={0},n,m,sum=0;//

int cmp(const Edge &a,const Edge &b)

{

return a.w

}

void input()

{

scanf("%d%d",&n,&m);

for(int i=1;i<=m;++i)

{

scanf("%d%d",&edge[i].u,&edge[i].v);

edge[i].w=i;

edge[i].next=head[edge[i].u];

head[edge[i].u]=i;

}

}

int find(int x)

{

if(father[x]!=x) father[x]=find(father[x]);

return father[x];

}

int k;

void unionn(int a,int b)

{

father[b]=a;

}

void kruskal()

{

k=0;

sort(edge+1,edge+m+1,cmp);

for(int i=1;i<=n;++i)

father[i]=i;

for(int i=1;i<=m;++i)

{

int r1=find(edge[i].u);

int r2=find(edge[i].v);

if(r1!=r2)

{

k++;

unionn(r1,r2);

sum++;

if(k==n-1) break;

}

}

}

int main()

{

input();

kruskal();

if(k==n-1)//表示图能连通
,一定是n-1条边

cout<<m-sum<<endl;

else cout<<"no way!"<<endl;//

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: