题意:
给出一张有N个点,N+1条边的图,问至少去掉一条边的情况下,使图仍然联通,有多少种方法。
思路:
N个点的图联通至少要N-1条边,那么就枚举去掉1条边和去掉2条边的情况,然后用并查集判断是否联通。
也可以用BFS判断,用DFS会超时。
1 #include <bits/stdc++.h> 2 using namespace std; 3 int T, n; 4 #define maxn 110 5 struct Edge 6 { 7 int a, b; 8 }e[maxn]; 9 int pre[maxn]; 10 int find(int x) 11 { 12 if(pre[x] == x) return x; 13 return find(pre[x]); 14 } 15 int main() 16 { 17 scanf("%d", &T); 18 while(T--) 19 { 20 scanf("%d", &n); 21 for(int i = 1; i <= n+1; i++) 22 { 23 int a, b; 24 scanf("%d%d", &a, &b); 25 e[i].a = a; e[i].b = b; 26 } 27 for(int i = 1; i <= n; i++) pre[i] = i; 28 int cnt = 0; 29 for(int i = 1; i <= n+1; i++) 30 { 31 int aa = find(e[i].a); 32 int bb = find(e[i].b); 33 if(aa != bb) pre[aa] = bb; 34 } 35 for(int i = 1; i <= n; i++) if(pre[i] == i) cnt++; 36 if(cnt != 1) { printf("0 "); continue;} 37 38 int sum = 0; 39 for(int i = 1; i <= n+1; i++) 40 { 41 for(int j = 1; j <= n; j++) pre[j] = j; 42 cnt = 0; 43 for(int j = 1; j <= n+1; j++) 44 { 45 if(j == i) continue; 46 int aa = find(e[j].a); 47 int bb = find(e[j].b); 48 if(aa != bb) pre[aa] = bb; 49 } 50 for(int j = 1; j <= n; j++) if(pre[j] == j) cnt++; 51 if(cnt == 1) sum++; 52 } 53 54 for(int i = 1; i <= n+1; i++) 55 { 56 for(int j = i+1; j <= n+1; j++) 57 { 58 for(int k = 1; k <= n; k++) pre[k] = k; 59 cnt = 0; 60 for(int k = 1; k <= n+1; k++) 61 { 62 if(k == i || k == j) continue; 63 int aa = find(e[k].a); 64 int bb = find(e[k].b); 65 if(aa != bb) pre[aa] = bb; 66 } 67 for(int k = 1; k <= n; k++) if(pre[k] == k) cnt++; 68 if(cnt == 1) sum++; 69 } 70 } 71 printf("%d ", sum); 72 } 73 return 0; 74 }