您的位置:首页 > 其它

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

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

给出一张 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: