Codeforces gym 102860I. Walk of Three 题解
题解
注意到,题目中仅需要走三步,要求是不可以走重复的路以及不可以回到 \(1\),由于步数很小,我们直接计算方案数:首先我们把和 \(1\) 相邻的点标记出来,之后遍历所有的点,统计其周围有多少个和 \(1\) 直接相连的点,假设对 \(i\) 来说是 \(\text{cnt}[i]\),则后两步可以看做从某一个入边进来,之后选一个不一样的再出去,刚好为 \(3\) 步:即 \[
\text{cnt}[i]\times(\text{cnt}[i]-1)
\]
每个点的方案(除了 \(1\))累加即可。(边用链表存会 TLE,换成 vector 存就不会,非常离谱)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include <cstdio> #include <cctype> #include <algorithm> #include <cstring> #include <iostream> #include <cassert> #include <vector> #include <cmath> using namespace std; typedef long long ll; template <typename _Tp> void read(_Tp &a, char c = 0, int f = 1) { for(c = getchar(); !isdigit(c); c = getchar()) if(c == '-') f = -1; for(a = 0; isdigit(c); a = a * 10 + c - '0', c = getchar()); a *= f; } template <typename _Tp> void write(_Tp a) { if(a < 0) putchar('-'), a = -a; if(a > 9) write(a / 10); putchar(a % 10 + '0'); }
const int N = 1e5 + 5; const int M = 2 * N;
int n, m;
vector<int> to[N];
bool t1[N]; int cnt[N];
int main() { read(n), read(m); while(m--) { int u, v; read(u), read(v); to[u].push_back(v); to[v].push_back(u); } for(auto x : to[1]) { t1[x] = 1; } for(int u = 1; u <= n; u++) { if(t1[u]) { for(auto v : to[u]) { cnt[v]++; } } } ll ans = 0; for(int i = 2; i <= n; i++) { if(cnt[i] > 1) ans += cnt[i] * (cnt[i] - 1); } write(ans), putchar('\n'); return 0; }
|