COJ--1541: There is No Alternative

来源:互联网 发布:捡宝贝淘宝u站 编辑:程序博客网 时间:2024/06/17 04:30

一个图的最小生成树可能不是唯一的,但是无论在那种组成中都可能会包含固定的几条边,这个题目就是要我们求出共有几条这样的边和他们的权重之和。
我们可以先求出一颗最小生成树,然后记录下组成这颗生成树的所有边,然后再依次去掉这些边,看还能不能得到同样权重的最小生成树,如果可以那么去掉的这条边就不是必须的。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define INF 0x3f3f3f3f#define maxn 510int fa[maxn],vis[maxn*100];typedef struct{    int x,y,w;}E;E e[51000],e1[51000];bool cmp(E e1,E e2){    return e1.w<e2.w;}int Find(int x){   return fa[x]==x? x:fa[x]=Find(fa[x]);}int join(int x,int y){    int fx=Find(x);    int fy=Find(y);    if(fx!=fy)    {        fa[fx]=fy;        return 1;    }    return 0;}int kruskal(int num,int flag,int x){    int sum=0,k=0;    for(int i=0;i<num;i++)    {        if(x==i)            continue;        if(join(e[i].x,e[i].y))        {           sum+=e[i].w;           if(flag)             vis[k++]=i;        }    }    return sum;}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i=1;i<=n;i++)            fa[i]=i;        for(int i=0;i<m;i++)            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);        sort(e,e+m,cmp);        int tmp=kruskal(m,1,-1);        int ans1=0,ans2=0;        for(int i=0;i<n-1;i++)        {            for(int i=1;i<=n;i++)                  fa[i]=i;            int sum=kruskal(m,0,vis[i]);            if(sum!=tmp)                ans1++,ans2+=e[vis[i]].w;        }        printf("%d %d\n",ans1,ans2);    }    return 0;}
1 0
原创粉丝点击