您的位置:首页 > 其它

hdu5631 Rikka with Graph 枚举+并查集

2016-02-24 22:27 239 查看
题意:

给出一张有N个点,N+1条边的图,问至少去掉一条边的情况下,使图仍然联通,有多少种方法。

思路:

N个点的图联通至少要N-1条边,那么就枚举去掉1条边和去掉2条边的情况,然后用并查集判断是否联通。

也可以用BFS判断,用DFS会超时。

#include <bits/stdc++.h>
using namespace std;
int T, n;
#define maxn 110
struct Edge
{
int a, b;
}e[maxn];
int pre[maxn];
int find(int x)
{
if(pre[x] == x) return x;
return find(pre[x]);
}
int main()
{
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = 1; i <= n+1; i++)
{
int a, b;
scanf("%d%d", &a, &b);
e[i].a = a; e[i].b = b;
}
for(int i = 1; i <= n; i++) pre[i] = i;
int cnt = 0;
for(int i = 1; i <= n+1; i++)
{
int aa = find(e[i].a);
int bb = find(e[i].b);
if(aa != bb) pre[aa] = bb;
}
for(int i = 1; i <= n; i++) if(pre[i] == i) cnt++;
if(cnt != 1) { printf("0\n"); continue;}

int sum = 0;
for(int i = 1; i <= n+1; i++)
{
for(int j = 1; j <= n; j++) pre[j] = j;
cnt = 0;
for(int j = 1; j <= n+1; j++)
{
if(j == i) continue;
int aa = find(e[j].a);
int bb = find(e[j].b);
if(aa != bb) pre[aa] = bb;
}
for(int j = 1; j <= n; j++) if(pre[j] == j) cnt++;
if(cnt == 1) sum++;
}

for(int i = 1; i <= n+1; i++)
{
for(int j = i+1; j <= n+1; j++)
{
for(int k = 1; k <= n; k++) pre[k] = k;
cnt = 0;
for(int k = 1; k <= n+1; k++)
{
if(k == i || k == j) continue;
int aa = find(e[k].a);
int bb = find(e[k].b);
if(aa != bb) pre[aa] = bb;
}
for(int k = 1; k <= n; k++) if(pre[k] == k) cnt++;
if(cnt == 1) sum++;
}
}
printf("%d\n", sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: