hdu 5631 Rikka with Graph【并查集】

来源:互联网 发布:品质退款率被淘宝管控 编辑:程序博客网 时间:2024/05/28 18:45

这里写图片描述
题意:
T组数据,一个数n,接下来n+1行表示边,问拆边后还能是这个图联通的方案数;
思路:
n+1条边,由MST可知,只需n-1条边就可已使图联通,只需要枚举拆除一条边的情况和拆除两条边的情况就可以了;用结构体存边,拿枚举一条边举例吧,枚举每一条边被拆除后看看是否连通,拆两条边时同理;

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define max_n 110int pre[max_n];int t,n,ans;struct node{    int a;    int b;}s[max_n];int find(int x){    if(pre[x]==x) return x;    return pre[x]=find(pre[x]);}int main(){    scanf("%d",&t);    while(t--)    {        ans=0;         scanf("%d",&n);        for(int i=0;i<=n;i++)            scanf("%d %d",&s[i].a,&s[i].b);        for(int i=0;i<=n;i++) //枚举拆除一条边         {            for(int j=1;j<=n;j++)                 pre[j]=j;            int res=0;            for(int j=0;j<=n;j++)             {                if(j==i) continue;                int fx=find(s[j].a);                int fy=find(s[j].b);                if(fx!=fy)                    pre[fy]=fx;            }            for(int j=1;j<=n;j++)            {                if(j==find(j))                {                    res++;                    if(res>1) break;                }            }            if(res<=1)                ans++;        }        for(int i=0;i<=n;i++) //枚举拆除两条边         {            for(int p=i+1;p<=n;p++)            {                int res=0;                for(int j=1;j<=n;j++)                    pre[j]=j;                for(int j=0;j<=n;j++)                 {                    if(j==i || j==p) continue;                    int fx=find(s[j].a);                    int fy=find(s[j].b);                    if(fx!=fy)                        pre[fy]=fx;                }                for(int j=1;j<=n;j++)                {                    if(j==find(j))                    {                        res++;                        if(res>1) break;                    }                }                if(res<=1)                    ans++;            }        }        printf("%d\n",ans);    }    return 0;}
原创粉丝点击