HDOJ 5631 Rikka with Graph (删边判断连通性)

问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

给出一张 nn 个点 n+1n+1 条边的无向图,你可以选择一些边(至少一条)删除。

现在勇太想知道有多少种方案使得删除之后图依然联通。

当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
第一行一个整数表示数据组数 T(T≤30)。

每组数据的第一行是一个整数 n(n≤100)n(n \leq 100)。

接下来 n+1 行每行两个整数 u,v 表示图中的一条边。
输出描述
对每组数据输出一行一个整数表示答案。
输入样例
1
3
1 2
2 3
3 1
1 3
输出样例
9


思路:因为总共有n+1条边,而一个联通图必须至少有n-1条边,那么最多删去两条边,所以说我们可以枚举删去的哪些边,然后判断联通性就行了。



ac代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stack>
#include<set>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#define MAXN 1010000
#define LL long long
#define ll __int64
#define INF 0xfffffff
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
#define eps 1e-8
using namespace std;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
//head
struct s
{
    int a,b;
}p[110];
int pri[110];
int n;
int find(int x)
{
    int r=x;
    while(r!=pri[r])
    r=pri[r];
    int i=x,j;
    while(i!=r)
    {
        j=pri[i];
        pri[i]=r;
        i=j;
    }
    return r;
}
int check(int aa,int bb)
{
    int i;
    for(i=1;i<=n;i++)
    pri[i]=i;
    for(i=0;i<=n;i++)
    {
        if(i==aa||i==bb)
        continue;
        int nx=find(p[i].a);
        int ny=find(p[i].b);
        if(nx!=ny)
        pri[nx]=ny;
    }
    int cnt=0;
    for(i=1;i<=n;i++)
    if(pri[i]==i)
    cnt++;
    return cnt==1?1:0;
}
int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<=n;i++)
        scanf("%d%d",&p[i].a,&p[i].b);
        int ans=0;
        for(i=0;i<=n;i++)
        {
            for(j=i;j<=n;j++)
            {
                if(check(i,j))
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(HDOJ 5631 Rikka with Graph (删边判断连通性))