URL編碼
阿新 • • 發佈:2020-11-24
Codeforces Round #686 (Div. 3)
E. Number of Simple Paths
思路:因為這個圖的邊和點的數量相等,所以保證圖上只有一個簡單環,我們找到這個環,把這個環上所有的邊斷掉,然後將這個環上所有點連向一個虛擬點 \(0\) ,以 \(0\) 為根(寫的時候不用這麼麻煩,這麼說只是為了便於理解),統計父節點是 \(0\) 的所有子樹的 \(sz_1, sz_2, sz_3 .... sz_k\) ,那麼答案就是 \((\sum_{i = 1}^k \sum_{j = i + 1}^k sz_i * sz_j + n * (n - 1)) / 2\)
我是用 \(dfs\)
#include <bits/stdc++.h> using namespace std; #define lc (rt << 1) #define rc ((rt << 1) | 1) #define fi first #define se second #define pb push_back #define pii pair<int, int> #define rep(i, l, r) for (int i = (l); i <= (r); ++i) #define per(i, r, l) for (int i = (r); i >= (l); --i) #define PE(i, u) for (int i = head[u]; i != -1; i = edge[i].next) typedef long long LL; const int maxn = 1e6 + 20; const int mod = 1e9 + 7; int n, m; struct Edge { int to, next; } edge[maxn * 2]; int k, head[maxn]; void add(int a, int b){ edge[k].to = b; edge[k].next = head[a]; head[a] = k++; } int d[maxn], dp[maxn], sz[maxn]; LL ans = 0; int sum; void dfs(int u, int fa){ sz[u] = 1; PE(i, u){ int to = edge[i].to; if(to == fa) continue; if(!d[to]) { d[to] = d[u] + 1; dfs(to, u); dp[u] += dp[to]; sz[u] += sz[to]; } else if(d[to] > d[u]) dp[u]--; else if(d[to] < d[u]) { dp[u]++; } } if(dp[u]) { ans += 1LL * (sum - sz[u]) * sz[u]; sum -= sz[u]; sz[u] = 0; } } int main(int argc, char const *argv[]) { int t; scanf("%d", &t); while(t--){ scanf("%d", &n); sum = n; ans = 0; ans = 1LL * n * (n - 1) / 2; rep(i, 1, n){ dp[i] = sz[i] = d[i] = 0; head[i] = -1; } rep(i, 1, n){ int u, v; scanf("%d%d", &u, &v); add(u, v), add(v, u); } d[1] = 1; dfs(1, 0); printf("%lld\n", ans); } return 0; }