CF1454E Number of Simple Paths

思路:

整个图可以看作是一个“环”和“挂”在上面的若干棵树组成的。首先找到这个“环”,然后分别计算上面每棵树包含的节点数,再计算同一棵树内及不同的树之间的路径数即可。可以使用图论算法也可以不使用。参考了https://codeforces.com/blog/entry/84984https://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 }
上一篇:LeetCode:所有可能的路径(深度优先搜索/广度优先搜索)


下一篇:大华视频控制对接相关