思路:
整个图可以看作是一个“环”和“挂”在上面的若干棵树组成的。首先找到这个“环”,然后分别计算上面每棵树包含的节点数,再计算同一棵树内及不同的树之间的路径数即可。可以使用图论算法也可以不使用。参考了https://codeforces.com/blog/entry/84984和https://www.cnblogs.com/dalt/p/8401432.html。
实现1:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int t; cin >> t; 6 while (t--) 7 { 8 int n; cin >> n; 9 vector<vector<int>> G(n + 1, vector<int>()); 10 vector<int> ind(n + 1, 0), cnt(n + 1, 0); 11 int a, b; 12 for (int i = 0; i < n; i++) 13 { 14 cin >> a >> b; 15 G[a].push_back(b); G[b].push_back(a); 16 ind[a]++; ind[b]++; 17 } 18 queue<int> q; 19 for (int i = 1; i <= n; i++) 20 { 21 cnt[i] = 1; 22 if (ind[i] == 1) q.push(i); 23 } 24 while (!q.empty()) 25 { 26 int t = q.front(); q.pop(); 27 for (int i = 0; i < G[t].size(); i++) 28 { 29 int s = G[t][i]; 30 if (cnt[s] == 0) continue; 31 cnt[s] += cnt[t]; 32 cnt[t] = 0; 33 ind[s]--; 34 if (ind[s] == 1) q.push(s); 35 } 36 } 37 long long res = 0; 38 for (int i = 1; i <= n; i++) 39 { 40 res += (long long)cnt[i] * (n - cnt[i]); 41 res += (long long)cnt[i] * (cnt[i] - 1) / 2; 42 } 43 cout << res << endl; 44 } 45 return 0; 46 }
实现2:
1 #include<bits/stdc++.h> 2 using namespace std; 3 vector<int> recover_path(stack<int>& st, int x) 4 { 5 vector<int> res; 6 while (!st.empty() and st.top() != x) 7 { 8 int t = st.top(); st.pop(); 9 res.push_back(t); 10 } 11 res.push_back(x); 12 return res; 13 } 14 vector<int> dfs(int x, int f, vector<vector<int>>& G, stack<int>& st, vector<bool>& vis) 15 { 16 vector<int> res; 17 for (int i = 0; i < G[x].size(); i++) 18 { 19 int t = G[x][i]; 20 if (t == f) continue; 21 if (vis[t]) { res = recover_path(st, t); return res; } 22 vis[t] = true; 23 st.push(t); 24 auto tmp = dfs(t, x, G, st, vis); 25 if (tmp.size() > 0) return tmp; 26 vis[t] = false; 27 st.pop(); 28 } 29 return res; 30 } 31 int dfs2(int x, vector<vector<int>>& G, vector<bool>& vis) 32 { 33 int res = 0; 34 for (int i = 0; i < G[x].size(); i++) 35 { 36 int t = G[x][i]; 37 if (vis[t]) continue; 38 vis[t] = true; 39 res += dfs2(t, G, vis); 40 } 41 return res + 1; 42 } 43 int main() 44 { 45 int t; cin >> t; 46 while (t--) 47 { 48 int n; cin >> n; 49 vector<vector<int>> G(n + 1, vector<int>()); 50 int a, b; 51 for (int i = 0; i < n; i++) 52 { 53 cin >> a >> b; 54 G[a].push_back(b); G[b].push_back(a); 55 } 56 stack<int> st; 57 vector<bool> vis(n + 1, 0); 58 vis[1] = true; 59 vector<int> res = dfs(1, 0, G, st, vis); 60 fill(vis.begin(), vis.end(), false); 61 for (auto it: res) vis[it] = true; 62 long long ans = 0; 63 vector<int> siz; 64 for (auto it: res) 65 { 66 int cnt = dfs2(it, G, vis); 67 siz.push_back(cnt); 68 } 69 for (int i = 0; i < siz.size(); i++) 70 { 71 ans += (long long)siz[i] * (siz[i] - 1) / 2; 72 ans += (long long)siz[i] * (n - siz[i]); 73 } 74 cout << ans << endl; 75 } 76 return 0; 77 }